我有一个像

line = u'I need to match the whole line except for {thisword for example'


我很难做到这一点。我尝试过的方法不起作用:

# in general case there will be Unicode characters in the pattern
matchobj = re.search(ur'[^\{].+', line)

matchobj = re.search(ur'(?!\{).+', line)


您能否帮助我找出问题所在以及正确的解决方法?

附言我认为我不需要用空字符串替换"{thisword"

最佳答案

我不清楚您需要什么。从问题标题看,您似乎想找到“字符串中所有不以{开头的单词,例如'line'”,但您使用的是re.search()函数,这使我感到困惑。

re.search()re.findall()

函数re.search()返回相应的MatchObject实例,re.serach通常用于匹配并返回长字符串中的模式。它不会返回所有可能的匹配项。参见下面的简单示例:

>>> re.search('a', 'aaa').group(0) # only first match
'a'
>>> re.search('a', 'aaa').group(1) # there is no second matched
Traceback (most recent call last):
  File "<console>", line 1, in <module>
IndexError: no such group


使用正则表达式'a'时,搜索仅返回字符串'a'中的一个模式'aaa',它不会返回所有可能的匹配项。

如果您要寻找目标–“字符串中的所有单词都不能以{开头”。您应该使用re.findall()函数:-匹配模式的所有出现,而不仅仅是re.search()的第一个模式。参见示例:

>>> re.findall('a', 'aaa')
['a', 'a', 'a']


编辑:在评论的基础上,再添加一个示例来演示re.search和re.findall的用法:

>>> re.search('a+', 'not itnot baaal laaaaaaall ').group()
'aaa'                 # returns ^^^   ^^^^^ doesn't
>>> re.findall('a+', 'not itnot baaal laaaaaaall ')
['aaa', 'aaaaaaa']    #          ^^^   ^^^^^^^ match both


这是有关Python重新模块的很好的教程:re – Regular Expressions

另外,Python-regex中有组的概念–“括号内的匹配模式”。如果您的正则表达式模式中存在多个组,则re.findall()返回组列表;如果模式包含多个组,则这将是一个元组列表。见下文:

>>> re.findall('(a(b))', 'abab') # 2 groups according to 2 pair of ( )
[('ab', 'b'), ('ab', 'b')] # list of tuples of groups captured


在Python中,正则表达式(a(b))包含两个组:作为两对括号(这与正式语言中的正则表达式不同–正则表达式与正则表达式并不完全相同
以正式语言表达,但这是另一回事)。



答:句子line中的单词用空格分隔(其他在字符串开头),正则表达式应为:

ur"(^|\s)(\w+)


正则表达式说明:


(^|\s+)的意思是:开始时是单词,或在某些空格后开始。
\w*:匹配字母数字字符,包括“ _”。


在将正则表达式r应用于行时:

>>> import pprint    # for pretty-print, you can ignore thesis two lines
>>> pp = pprint.PrettyPrinter(indent=4)

>>> r = ur"(^|\s)(\w+)"
>>> L = re.findall(r, line)
>>> pp.pprint(L)
[   (u'', u'I'),
    (u' ', u'need'),
    (u' ', u'to'),
    (u' ', u'match'),
    (u' ', u'the'),
    (u' ', u'whole'),
    (u' ', u'line'),
    (u' ', u'except'),
    (u' ', u'for'),   # notice 'for' after 'for'
    (u' ', u'for'),   # '{thisword' is not included
    (u' ', u'example')]
>>>


要查找一行中的所有单词,请使用:

>>> [t[1] for t in re.findall(r, line)]


注意:它将避免{或行中的任何其他特殊字符,因为\ w仅传递字母数字和'_'字符。



如果您只避免在单词的开头出现{(允许在中间出现),则使用正则表达式:r = ur"(^|\s+)(?P<word>[^{]\S*)"

要了解此正则表达式与其他正则表达式之间的区别,请检查以下示例:

>>> r = ur"(^|\s+)(?P<word>[^{]\S*)"
>>> [t[1] for t in re.findall(r, "I am {not yes{ what")]
['I', 'am', 'yes{', 'what']




没有正则表达式:

您无需任何正则表达式就可以实现相同的目的,如下所示:

>>> [w for w in line.split() if w[0] != '{']




re.sub()替换模式

如果您只想替换以{开头的一个(或多个)单词,则应使用re.sub()用示例字符串{替换以""开头的模式,请检查以下代码:

>>> r = ur"{\w+"
>>> re.findall(r, line)
[u'{thisword']
>>> re.sub(r, "", line)
u'I need to match the whole line except for  for example'




编辑添加评论的回复:

(?P<name>...)是Python的Regex扩展名:(在Python中具有含义)-(?P<name>...)类似于常规括号-创建一个组(一个命名组)。可通过符号组名访问该组。组名必须是有效的Python标识符,并且每个组名必须在正则表达式中仅定义一次。示例1:

>>> r = "(?P<capture_all_A>A+)"
>>> mo = re.search(r, "aaaAAAAAAbbbaaaaa")
>>> mo.group('capture_all_A')
'AAAAAA'


示例2:假设您要从可能包含标题的名称行中过滤名称,例如mr使用正则表达式:name_re = "(?P<title>(mr|ms)\.?)? ?(?P<name>[a-z ]*)"

我们可以使用group('name')读取输入字符串中的名称:

>>> re.search(name_re, "mr grijesh chauhan").group('name')
'grijesh chauhan'
>>> re.search(name_re, "grijesh chauhan").group('name')
'grijesh chauhan'
>>> re.search(name_re, "ms. xyz").group('name')
'xyz'

关于python - 匹配字符串中的任何单词,但在python中以大括号开头的单词除外,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23030330/

10-12 00:24
查看更多