否定先前匹配的单词组

时间:2013-03-04 18:24:42

标签: python regex pattern-matching

我正在尝试从字符串中提取内容,如下所示:

A.content content 
  content 
B.content  C. content content
content D.content

这是我在Python中的正则表达式模式:

reg = re.compile(r''' 
     (?xi)
     (\w\.\t*\s*)+ (?# e.g. A. or b.)
     (.+)          (?# the alphanumeric content with common symbols)
     ^(?:\1)       (?# e.g. 'not A.' or 'not b.')
     ''')

m = reg.findall(s)

让我举个例子。说我有以下字符串:

s = '''
 a.   $1000 abcde!?
 b.  (December 31, 1993.)
 c.  8/1/2013
 d.   $690 * 10% = 69 Blah blah
'''

以下正则表达式有效并向我返回正则表达式组的内容:

reg = re.compile(r'''
            (?xi)
            \w\.\t*
            ([^\n]+) (?# anything not newline char)
''')

for c in reg.findall(s): print "line:", c
>>>line:    $1000 abcde!?
>>>line:  (December 31, 1993.)
>>>line:    8/1/2013
>>>line:   $690 * 10% = 69 Blah blah

如果内容渗透到另一行,则正则表达式无法正常工作

s = '''
   a.   $1000 abcde!? B.     December 
   31, 1993 c.  8/1/2013 D.   $690 * 10% = 
   69 Blah blah
'''
reg = re.compile(r''' 
     (?xi)
     (\w\.\t*\s*)+ (?# e.g. A. or b.)
     (.+)          (?# the alphanumeric content with common symbols)
     ^(?:\1)       (?# e.g. 'not A.' or 'not b.')
     ''')
for c in reg.findall(s): print "line:", c # no matches :(
>>> blank :(

我想获得相同的匹配,无论是否有新行分隔内容。

这就是我尝试使用否定匹配词组的原因。那么关于如何使用正则表达式或其他一些解决方法解决这个问题的任何想法?

感谢。

1 个答案:

答案 0 :(得分:1)

认为我明白你想要什么。你想拆分

a.   $1000 abcde!? B.     December 
31, 1993 c.  8/1/2013 D.   $690 * 10% = 
69 Blah blah

  • a. $1000 abcde!?
  • B. December \n31, 1993
  • c. 8/1/2013
  • D. $690 * 10% = \n69 Blah blah

右?那么负面的先行断言就是你想要的:

reg = re.compile(r''' 
     (?xs)               # no need for i, but for s (dot matches newlines)
     (\b\w\.\s*)         # e.g. A. or b. (word boundary to restrict to 1 letter)
     ((?:(?!\b\w\.).)+)  # everything until the next A. or b.
     ''')

findall()

一起使用
>>> reg.findall(s)
[('a.   ', '$1000 abcde!? '), ('B.     ', 'December \n   31, 1993 '), 
 ('c.  ', '8/1/2013 '), ('D.   ', '$690 * 10% = \n   69 Blah blah\n')]

如果您不想要a.部分,请使用

reg = re.compile(r''' 
     (?xs)               # no need for i, but for s (dot matches newlines)
     (?:\b\w\.\s*)       # e.g. A. or b. (word boundary to restrict to 1 letter)
     ((?:(?!\b\w\.).)+)  # everything until the next A. or b.
     ''')