正则表达式用于多行文本的一部分,包括所有类型的字符,包括换行符、@、^、'、"等



我有一个大文本,它在由开始和结束分隔的小节中决定。我想提取中间不变的文本,同时提取文本中部分的名称。我失败了,因为我使用了。+在我的正则表达式中,我总是得到全文。我还不得不用另一种技巧提取零件名称,因为我无法在命名组中捕捉到它。因此,我构建了一个以名称作为regex输入的字符串,但它仍然失败为。+贪婪,抓住了整个文本。

我失败的正则表达式:

regex_string = '^!!sSTARTs' + partname + 's!!(?P<part_text>.*)'
REGEXP_CONTEXT_CONFIG = re.compile(regex_string, re.DOTALL)

要捕获的测试文本:

!! START goblin !!
text to capture
that is multiline 
and contains all sort 
of special chars 
!! END goblin !!
!! START berta !!
text to capture
that is multiline 
and contains all sort 
of special chars 
!! END berta !!
!! START vlad !!
text to capture
that is multiline 
and contains all sort 
of special chars 
!! END Vlad !!

我尝试归档的是一个regex,它捕获两个命名组中的部分名称和包含文本的部分。

您可以使用类似的正则表达式

(?smi)^!! START (?P<part_name>goblin|berta|vlad) !!(?P<part_text>.*?)!! END (?P=part_name) !!

请参阅regex演示。

详细信息

  • (?smi)点现在匹配换行符(s(,^也匹配行首(m(,并且模式不区分大小写(i(
  • ^-线路起点
  • !! START-文字字符串
  • (?P<part_name>goblin|berta|vlad)-组"part_name"捕获其中一个名称
  • !!-文字
  • (?P<part_text>.*?)-组"part_text":任意0+个字符,尽可能少
  • !! END-文字字符串
  • (?P=part_name)-与组"part_name"中捕获的文本相同
  • !!-文本

在代码中,使用

partnames = ['goblin', 'berta', 'vlad']
regex_string = '^!! START (?P<part_name>{}) !!(?P<part_text>.*?)!! END (?P=part_name) !!'.format("|".join(partnames))
REGEXP_CONTEXT_CONFIG = re.compile(regex_string, re.DOTALL | re.M| re.I)
print( REGEXP_CONTEXT_CONFIG.findall(text) )
# => [('goblin', 'ntext to capturenthat is multiline nand contains all sort nof special chars n'), ('berta', 'ntext to capturenthat is multiline nand contains all sort nof special chars n'), ('vlad', 'ntext to capturenthat is multiline nand contains all sort nof special chars n')]

请参阅Python演示。您可以稍后从零件文本中删除前导/尾随空格。

正则表达式有几个问题:

  • 没有结束标记

  • 贪婪的模式可以通过在它们后面打一个问号来变得不贪婪:.*?.+?

  • 您需要使用re.MULTILINE,否则^只在全文的开头匹配(而不是在每行的开头(。

  • 我在示例文本中放了一个1、2或3,否则你仍然看不到是否进行了正确的匹配


text = """
!! START goblin !!
text 1 to capture
that is multiline
and contains all sort
of special chars
!! END goblin !!
!! START berta !!
text 2 to capture
that is multiline
and contains all sort
of special chars
!! END berta !!
!! START vlad !!
text 3 to capture
that is multiline
and contains all sort
of special chars
!! END Vlad !!
"""
import re
partname = "berta"
pattern = '^!!sSTARTs' + partname + 's!!(?P<part_text>.*)!!sENDs' + partname + 's!!'
regex = re.compile(pattern, re.DOTALL|re.MULTILINE)
match = regex.search(text)
print(match.group('part_text'))

输出:

text 2 to capture
that is multiline
and contains all sort
of special chars

(您可能需要播放一点以消除空换行符。或者只使用match.group('part_text').strip()(。

我想我已经在这里的评论和答案的帮助下找到了一个可行的解决方案。非常感谢!

re.compile('^!!sSTARTs(?P<part_name>w+)s!!(?P<part_text>.*?)!!sENDsw+s!!', re.DOTALL|re.MULTILINE)

最新更新