1

我正在使用该sub()功能替换===Something here===<h2>Something here</h2>.

以下是有效的:

line = sub(r"(===)([a-zA-Z\s]*)(===)", r"<h2>\2</h2>", line)

原始内容在哪里:

===Something here===

但是,当原始内容为:

===
Something here
===

我试过这样的事情:

line = sub(r"(===\n)([a-zA-Z\s]*)(===)", r"<h2>\2</h2>", line)

(唯一的变化是\n在第一组中添加了)

但我认为这强制模式包含一个新行,而不是作为模式的可选部分。

如何扩展当前模式,使其足够灵活以识别可能存在新行的实例?

编辑:

我已经尝试了以下建议(在撰写本文时),但它们不起作用。我能想到的唯一原因是因为该行中可能还有其他字符。

以下图像是正在读取的原始文本文件的屏幕截图(在 SciTE 编辑器中打开,“行尾”和“空白”设置为显示):

original_text_file = open('file.txt', 'U')

单行实例:

在此处输入图像描述

多行实例:

在此处输入图像描述

不知道这些角色是否需要考虑其他因素?

编辑二:

测试下面另一个解决方案的结果(这没有在多行实例上执行替换):

蟒蛇代码:

from re import *

def test_function(text_file):
    file_object = open(text_file+'.txt', 'U')
    for line in file_object:
        line = sub(r"\n?(===)\n?([a-zA-Z\s]*?)\n?(===)\n?\n?", r"<h2>\2</h2>", line)
        print line

test_function('my_file')

my_file.txt:

===Something here===

Lorem ipsum lala.  

===
Something here
===

Loreum ipsum lala.  
4

5 回答 5

1

我建议这个解决方案:

import re
s = """===Something here===

Lorem ipsum lala.  

===
Something here
===

Loreum ipsum lala.  """
result = re.sub(r"===(.*?)===", r"<h2>\1</h2>", s, flags=re.DOTALL)
print result

一些解释:

  • .*?匹配“非贪婪”模式下的任何字符:匹配尽可能少的数据。这是为了避免===First=== lalala ===Second===被替换为<h2>First=== lalala ===Second</h2>

  • flags=re.DOTALL表示.匹配任何字符,包括换行符

请注意,您需要将 sub() 应用于整个文件,而不是逐行

于 2013-05-18T07:57:25.283 回答
1

使用 flag 编译正则表达式re.DOTALL:这将使字符.也匹配换行符。$应该用于强制结束模式。您不再需要\s在 Blender 的解决方案中使用。

于 2013-05-18T08:08:04.097 回答
1

我认为在这里使用正则表达式是合适的。你的表情接近你所需要的。在\n您需要?匹配01出现之前的字符之后,在本例中为 0 或 1 \n。这必须放置在多个位置以应对可能的换行符。您还必须使\s目标捕获组中的 不消耗可选项\n,否则您最终会\n在输出中得到 a 。

import re
pat = r'\n?(===)\n?([a-zA-Z\s]*?)\n?(===)\n?\n?'
rep = r'<h2>\2</h2>'

print(repr(re.sub(pat,rep,"""
=== Something here ===
""")))
print(repr(re.sub(pat,rep,"""===
Something here
===""")))

输出

>>> 
'<h2> Something here </h2>'
'<h2>Something here</h2>'

我像你一样从 Scite 复制并粘贴了文本:

在此处输入图像描述


对于多线我会推荐这个:

import re
patSearch = r'\n?===\n?[a-zA-Z\s]*?\n?==='
patReplace = r'\n?(===)\n?([a-zA-Z\s]*?)\n?(===)\n?\n?'
replacement  = r'<h2>\2</h2>'

用一个字符串t

t="""===Something here===

Lorem ipsum lala.  

===
Something here
===

Loreum ipsum lala."""

以下

matches = re.findall(patSearch,t) #get all the === ... === style string
for match in matches:
    print re.sub(patReplace,replacement,match) #do replacement in each one

会产生

>>> 
<h2>Something here</h2>
<h2>Something here</h2>
于 2013-05-18T02:57:58.553 回答
0

在捕获组之间添加空格:

re.sub(r"(===)\s*([a-zA-Z\s]*?)\s*(===)", r"<h2>\2</h2>", line)

您还可以使用非贪婪捕获组:

re.sub(r"(===)\s*(.*?)\s*(===)", r"<h2>\2</h2>", line)
于 2013-05-18T02:57:30.277 回答
0

User1063287,如果您仍有问题,我推荐 Zac 发布的解决方案。我遇到了和你类似的问题,'re.DOTALL' 标志是让我的替换按我的意图发生的技巧。我的问题还涉及从 .txt 文件访问文本。这是关于如何根据对我有用的方法编写特定问题的建议(请注意,我将输出保存到新的 .txt)

import re
with open('output.txt', "w") as o:
    with open('input', 'r') as i:
        line = i.read()
        line = re.sub(r"===.*?===", r"<h2>\2</h2>", line, flags=re.DOTALL)      
    o.write(line)

with 语句将允许您的输入和输出文件在循环完成时关闭,并且 i.read() 命令允许一次读取整个文件(而不是逐行访问)。我不明白您为什么不能将此代码放入 def 函数中,但我还没有尝试确定。

祝你好运!

于 2015-05-15T21:07:02.203 回答