几天来,我一直在调整一个正则表达式,试图用一个单一的定义来捕获数据库地址字段中格式不一致的几种情况。
我是Python和正则表达式的新手,在stackoverflow中得到了很好的反馈,用我的新知识,我构建了一个接近最终结果的RegEx,但仍然找不到问题所在。
import re
r1 = r"([\w\s+]+),?\s*\(?([\w\s+\\/]+)\)?\s*\(?([\w\s+\\/]+)\)?"
match1 = re.match(r1, 'caracas, venezuela')
match2 = re.match(r1, 'caracas (venezuela)')
match3 = re.match(r1, 'caracas, (venezuela) (df)')
group1 = match1.groups()
group2 = match2.groups()
group3 = match3.groups()
print group1
print group2
print group3对于组1和组2,它应该返回'caracas,委内瑞拉‘,对于组3,它应该返回'caracas,委内瑞拉,df’,相反,它返回:
('caracas', 'venezuel' 'a')
('caracas ', 'venezuel' 'a')
('caracas', 'venezuela', 'df')唯一完美的匹配是第三组。另外两组在末尾隔离了'a‘,第二组在'caracas’的末尾有一个额外的空格。提前感谢你的见解。
干杯!
发布于 2012-04-06 07:19:32
正则表达式可能太过分了.你的问题陈述到底是什么?您需要捕获哪些内容?
我注意到了一些事情(按照在regex中出现的顺序;有时从左到右,以英式风格读出它会很有帮助):
([\w\s+]+)这表示“捕获一个或多个(字母或一个或多个空格)”
您真的想要捕获城市名称末尾的空格吗?此外,您不需要(实际上不应该)在括号[ ]中包含1个或多个符号+,因为您的正则表达式已经根据外部+匹配了其中的一个或多个符号。我会像这样重写这一部分:
([\w\s]*\w)它将急切地匹配到最后一个字母数字字符(“零个或多个(字母或空格)后跟一个字母”)。这确实假设您至少有一个字符,但比您认为一个空格也可以工作的假设要好。
接下来,您需要:
,?\s*\(?这对我来说没问题,只是它不能保证你会再看到逗号或空格。下面是什么:
(?:,\s*\(|,\s*|\s*\()上面写着,“非诱人地匹配(一个逗号,可能有一些空格,然后是一个开放的paren)或者(一个逗号,可能有一些空格)或者(可能是一些空格,然后是一个开放的paren)”。这强制要求您必须有逗号或paren,或者两者都有。
接下来是捕获表达式,非常类似于第一个表达式:
([\w\s+\\/]+)同样,您不希望在城市名称的末尾使用空格(在本例中为斜杠),也不希望[ ]中的+
([\w\s\\/]*\w)下一个表达式可能是您遇到venezuel a问题的地方;让我们来看看:
\)?\s*\(?([\w\s+\\/]+)\)?这是一个相当长的问题,所以让我们将其分解:
\)?\s*\(?说“也许可以匹配一个接近的paren,然后可能是一些空格,然后可能是一个开放的paren”。我想这没问题,让我们来看看真正的问题:
([\w\s+\\/]+)此捕获组必须至少匹配一个字符。如果匹配器在您的地址末尾看到“委内瑞拉”,它将急切地字符venezuel,然后需要用剩下的a来满足最后一个表达式。相反,尝试:
\)?\s*然后将整个最终表达式设为可选,并将外部表达式设为非捕获:
(?:\(?([\w\s+\\/]+)\)?)?最后的表达式是:
([\w\s]*\w)(?:,\s*\(|,\s*|\s*\()([\w\s\\/]*\w)\)?\s*(?:\(?([\w\s+\\/]+)\)?)?编辑:修复了一个问题,使最终的组捕获两次,一次与父母,一次没有。现在,它应该只捕获括号内的文本。
在您的示例中进行测试:
>>> re.match(r, 'caracas, venezuela').groups()
('caracas', 'venezuela', None)
>>> re.match(r, 'caracas (venezuela)').groups()
('caracas', 'venezuela', None)
>>> re.match(r, 'caracas, (venezuela) (df)').groups()
('caracas', 'venezuela', 'df')发布于 2012-04-06 06:45:16
你能不能找出课文中的所有单词?
例如:
>>> import re
>>> samples = ['caracas, venezuela','caracas (venezuela)','caracas, (venezuela) (df)']
>>>
>>> def find_words(text):
... return re.findall('\w+',text)
...
>>> for sample in samples:
... print find_words(sample)
...
['caracas', 'venezuela']
['caracas', 'venezuela']
['caracas', 'venezuela', 'df']https://stackoverflow.com/questions/10036973
复制相似问题