繁体   English   中英

正则表达式替换替换行问题

[英]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]"作用是寻找目标字符串中与匹配集匹配的最后一个字符。 这是它尾部的最后一个txt...\\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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM