我有一个像
这样的字符串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)
你能帮我弄清楚什么是错的,怎么做对了?
P.S。我认为我不需要用空字符串
替换"{thisword"
答案 0 :(得分:2)
我不清楚你需要什么。从你的问题标题它看起来你想找到“字符串中的所有单词,例如'行',这些不是以{”开头,但你使用的是re.search()函数让我困惑。
re.search()
和re.findall()
函数re.search()
返回 a 对应的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模块的一个很好的教程:re – Regular Expressions
此外,Python-regex中有group的概念 - “括号内的匹配模式”。如果正则表达式模式中存在多个组,则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()
替换模式以{
替换emplty string ""
检查以下代码:
>>> 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标识符,并且每个组名只能在正则表达式中定义一次。 example-1:
>>> r = "(?P<capture_all_A>A+)"
>>> mo = re.search(r, "aaaAAAAAAbbbaaaaa")
>>> mo.group('capture_all_A')
'AAAAAA'
example-2:假设您想从名称行中过滤名称,例如使用正则表达式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'
答案 1 :(得分:1)
答案 2 :(得分:0)
尝试这种模式:
(.*)(?:\{\w+)\s(.*)
<强>代码:强>
import re
p = re.compile(r'(.*)(?:\{\w+)\s(.*)')
str = "I need to match the whole line except for {thisword for example"
p.match(str)
示例:强>