正则表达式

时间:2016-04-29 12:40:54

标签: python regex python-2.7

我正在努力学习正则表达式。我有问题让我的头缠绕在较大的文本嵌套的类似文本。也许你可以帮助我整理我的想法。

以下是一个示例测试字符串:

message msgName { stuff { innerStuff } } \n message mn2 { junk }

我想拉出术语(例如,msgNamemn2)以及下一条消息之后的内容,以获得这样的列表:

msgName 
{ stuff { innerStuff } more stuff } 
mn2 
{ junk }'

我太贪婪或不贪婪地匹配以保留内部括号但将更高级别的消息分开。

这是一个程序:

import re
text = 'message msgName { stuff { innerStuff } more stuff } \n message mn2 { junk }'
messagePattern = re.compile('message (.*?) {(.*)}', re.DOTALL)
messageList = messagePattern.findall(text)
print "messages:\n"
count = 0
for message, msgDef in messageList:
    count = count + 1
    print str(count)
    print message
    print msgDef

它产生:

messages:

1
msgName
 stuff { innerStuff } more stuff } 
 message mn2 { junk 

这是我的下一次尝试,它使内部部分非贪婪:

import re
text = 'message msgName { stuff { innerStuff } more stuff } \n message mn2 { junk }'
messagePattern = re.compile('message (.*?) {(.*?)}', re.DOTALL)
messageList = messagePattern.findall(text)
print "messages:\n"
count = 0
for message, msgDef in messageList:
    count = count + 1
    print str(count)
    print message
    print msgDef

它产生:

messages:

1
msgName
 stuff { innerStuff 
2
mn2
 junk 

所以,我失去了} more stuff }

我真的遇到了这个问题。有人能指出我正确的方向吗?我没有处理嵌套括号中的文本。关于工作正则表达式的建议或处理嵌套的类似文本的简单示例会有所帮助。

1 个答案:

答案 0 :(得分:1)

如果您可以使用PyPi regex module,则可以利用其子程序调用支持:

>>> import regex
>>> reg = regex.compile(r"(\w+)\s*({(?>[^{}]++|(?2))*})")
>>> s = "message msgName { stuff { innerStuff } } \n message mn2 { junk }"
>>> print(reg.findall(s))
[('msgName', '{ stuff { innerStuff } }'), ('mn2', '{ junk }')]

正则表达式 - (\w+)\s*({(?>[^{}]++|(?2))*}) - 匹配:

  • (\w+) - 第1组匹配1个或多个字母数字/下划线字符
  • \s* - 0+空格
  • ({(?>[^{}]++|(?2))*}) - 第2组与{匹配,后跟非 - {}或其他均衡{...},原因是(?2)子程序调用(全部递归)第2组子模式,0次或更多次,然后匹配结束}

如果只有一个嵌套级别,re也可以使用

(\w+)\s*{[^{}]*(?:{[^{}]*}[^{}]*)*}

请参阅此regex demo

  • (\w+) - 第1组匹配的字符
  • \s* - 0+ whitespaces
  • { - 大括号
  • [^{}]* - 除{}
  • 以外的0个字符
  • (?:{[^{}]*}[^{}]*)* - 0+序列:
    • { - 大括号
    • [^{}]* - 除{}
    • 以外的0个字符
    • } - 右大括号
    • [^{}]* - 除{}
    • 以外的0个字符
  • } - 右大括号