【问题标题】:How to use REGEX with multiline如何将正则表达式与多行一起使用
【发布时间】:2017-02-28 08:18:05
【问题描述】:

以下表达式可以很好地提取data 字符串中以单词Block 开头、后跟左括号{ 并以右括号'}' 结尾的部分:

data ="""
Somewhere over the rainbow
Way up high 
Block {
 line 1
 line 2
 line 3
}
And the dreams that you dreamed of
Once in a lullaby
"""
regex = re.compile("""(Block\ {\n\ [^\{\}]*\n}\n)""", re.MULTILINE)
result = regex.findall(data)
print result 

返回:

['Block {\n line 1\n line 2\n line 3\n}\n']

但如果字符串的 Block 部分内有另一个大括号,则表达式会中断,返回一个空列表:

data ="""
Somewhere over the rainbow
Way up high 
Block {
 line 1
 line 2
 {{}
 line 3
}
And the dreams that you dreamed of
Once in a lullaby
Block {
 line 4
 line 5
 {{
 }
 line 6
}
Somewhere over the rainbow
Blue birds fly
And the dreams that you dreamed of
Dreams really do come true ooh oh
"""

如何修改此正则表达式以使其忽略 Blocks 内的括号,但每个块都作为 result 列表中的单独实体返回(因此可以单独访问每个 Block)?

【问题讨论】:

  • 实际上[^{}]* 阻止匹配任何左大括号。请注意,MULTILINE 标志不是您想的那样。 (它不是为了匹配分布在多行的字符串,它只会改变锚点^$的含义。为了让点匹配换行符,标志是DOTALL)
  • 既然你编辑了你的问题:这个问题不能用 re 模块解决,你需要处理递归的 regex 模块。请注意,您需要为未确定的情况选择默认行为。

标签: python regex


【解决方案1】:

这不行吗?

regex = re.compile("""(Block\ {\n\ [^\}]*\n}\n)""", re.MULTILINE)

在您发布的版本中,只要遇到第二个左大括号,它就会退出匹配,即使您希望它在第一个右大括号时退出。如果您想要嵌套的开/关大括号,那就另当别论了。

【讨论】:

  • 如果有内部括号 } ,您的表达式将返回一个空列表。
  • 具体是什么关闭了区块? \n\}\n?
  • 是的,区块总是以\n\}\n 关闭。它总是以Block\ {\n 开头
【解决方案2】:

我建议你使用:

(Block ?{\n ?[^$]+?\n}\n)

由于python匹配greedy,我们用?表示非贪婪。

对我来说效果很好。 另外我建议你使用https://regex101.com/

最好的问候

【讨论】:

  • 感谢您的回答!但是您的表达式将两个块作为列表中的单个实体返回。它只考虑第一个括号和最后一个括号。
  • 您的修改效果很好:(Block ?{\n ?[^$]+?\n}\n)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-18
  • 2016-12-29
  • 2011-06-19
  • 2012-06-23
  • 1970-01-01
相关资源
最近更新 更多