[英]Regex substitution replacement line issue
我正在尝试以以下文本变量打印的形式制作文本:
"""Chapter # 章节标题
介绍
高质量的文字..."""
相反,我得到:
"""Chapter # 章节标题
X
……"""
我什至无法开始弄清楚错误。 X甚至来自哪里? 这没有意义,所以我不知道我需要解决什么问题。 有人知道是什么问题吗?
import re
text = """
...Garbage text prior to start
INTRODUCTION
Top quality text...
"""
file_name = 'Chapter # Chapter title'
def clip_beginning(text):
'''Removes all text prior to the keyword'''
beginning_phrase_list = ['INTRODUCTION', 'Starting section 2']
processed_text = re.sub(rf'(.|\n)*{beginning_phrase_list}', rf'{file_name}\n\1\n', text)
return processed_text
text = clip_beginning(text)
print(text)
这就是你的目标吗? 问题不在于使用rf
。
解决方案
>>> text = '\n...Garbage text prior to start\n\nINTRODUCTION\n\nTop quality text...\n'
>>>
>>> beginning_phrase_list = ['INTRODUCTION', 'Starting section 2']
>>>
>>> file_name = 'Chapter # Chapter title'
>>>
>>> result = re.sub(rf"^.*?({'|'.join(beginning_phrase_list)})",
... rf"{file_name}\n\n\1", text, flags=re.DOTALL)
>>>
>>> print(result)
Chapter # Chapter title
INTRODUCTION
Top quality text...
>>> # The expression, when evaluated becomes...
>>>
>>> becomes = rf"^.*?({'|'.join(beginning_phrase_list)})"
>>> becomes
'^.*?(INTRODUCTION|Starting section 2)'
>>>
您在表达式中使用了与垃圾匹配的分组,然后将其放入带有\\1
的替换字符串中。 我更改了分组以匹配短语列表。 并将短语列表匹配表达式更新为列表的 OR 连接。
flags=re.DOTALL
告诉re.sub()
用点匹配换行符.
.
插入符号^
告诉re.sub()
从字符串的开头开始匹配 - 这确保捕获所有垃圾。
在正则表达式匹配和替换中使用rf
很好,事实上它为匹配和替换操作提供了一些非常优雅的解决方案。
神秘的X
>>> # The way it was before...
>>>
>>> evaluates_to = rf'(.|\n)*{beginning_phrase_list}'
>>> evaluates_to
"(.|\\n)*['INTRODUCTION', 'Starting section 2']"
你的表达相当于:
"(.|\\n)*[ ',2CDINORSTUaceginorst]"
注意[...]
匹配集。 通过将变量beginning_phrase_list
放在表达式中,您创建了一个匹配集,因为列表在字符串化时有方括号。
这就是我如何将它转换成那个奇怪的集合:
>>> match_set = list( set( str(beginning_phrase_list)[1:-1] ) )
>>> match_set.sort()
>>>
>>> '[' + ''.join(match_set) + ']'
"[ ',2CDINORSTUaceginorst]"
这个表达式"(.|\\\\n)*[ ',2CDINORSTUaceginorst]"
作用是寻找目标字符串中与匹配集匹配的最后一个字符。 这是它尾部的最后一个t
: xt...\\n
。
最后一个t
前面是x
,它被捕获组(.|\\n)
捕获。 括号创建一个捕获组。 而那个x
就是\\1
反向引用在您的替换字符串rf'{file_name}\\n\\1\\n'
引用rf'{file_name}\\n\\1\\n'
。
捕获组和星号(.|n)*
只为一个字符创建一个捕获组,因为星号不在括号内的表达式内。 单独的表达式匹配最后一个t
之前的每个字符,但只有最后一个包含在捕获组中。
X 大写是因为……因为你大写了它。 它实际上在输出中显示为“x”。
你有它......比你预期的更多的分析=)
改变...
processed_text = re.sub(rf'(.|\n)*{beginning_phrase_list}', rf'{file_name}\n\1\n', text)
到...
processed_text = re.sub(r'(.|\n)*{beginning_phrase_list}', f'{file_name}\n\1\n', text)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.