首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python中的正则表达式,用于捕获多种格式错误的地址

python中的正则表达式,用于捕获多种格式错误的地址
EN

Stack Overflow用户
提问于 2012-04-06 06:36:23
回答 2查看 130关注 0票数 0

几天来,我一直在调整一个正则表达式,试图用一个单一的定义来捕获数据库地址字段中格式不一致的几种情况。

我是Python和正则表达式的新手,在stackoverflow中得到了很好的反馈,用我的新知识,我构建了一个接近最终结果的RegEx,但仍然找不到问题所在。

代码语言:javascript
复制
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’,相反,它返回:

代码语言:javascript
复制
('caracas', 'venezuel' 'a') 
('caracas ', 'venezuel' 'a')
('caracas', 'venezuela', 'df')

唯一完美的匹配是第三组。另外两组在末尾隔离了'a‘,第二组在'caracas’的末尾有一个额外的空格。提前感谢你的见解。

干杯!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-04-06 07:19:32

正则表达式可能太过分了.你的问题陈述到底是什么?您需要捕获哪些内容?

我注意到了一些事情(按照在regex中出现的顺序;有时从左到右,以英式风格读出它会很有帮助):

代码语言:javascript
复制
([\w\s+]+)

这表示“捕获一个或多个(字母或一个或多个空格)”

您真的想要捕获城市名称末尾的空格吗?此外,您不需要(实际上不应该)在括号[ ]中包含1个或多个符号+,因为您的正则表达式已经根据外部+匹配了其中的一个或多个符号。我会像这样重写这一部分:

代码语言:javascript
复制
([\w\s]*\w)

它将急切地匹配到最后一个字母数字字符(“零个或多个(字母或空格)后跟一个字母”)。这确实假设您至少有一个字符,但比您认为一个空格也可以工作的假设要好。

接下来,您需要:

代码语言:javascript
复制
,?\s*\(?

这对我来说没问题,只是它不能保证你会再看到逗号或空格。下面是什么:

代码语言:javascript
复制
(?:,\s*\(|,\s*|\s*\()

上面写着,“非诱人地匹配(一个逗号,可能有一些空格,然后是一个开放的paren)或者(一个逗号,可能有一些空格)或者(可能是一些空格,然后是一个开放的paren)”。这强制要求您必须有逗号或paren,或者两者都有。

接下来是捕获表达式,非常类似于第一个表达式:

代码语言:javascript
复制
([\w\s+\\/]+)

同样,您不希望在城市名称的末尾使用空格(在本例中为斜杠),也不希望[ ]中的+

代码语言:javascript
复制
([\w\s\\/]*\w)

下一个表达式可能是您遇到venezuel a问题的地方;让我们来看看:

代码语言:javascript
复制
\)?\s*\(?([\w\s+\\/]+)\)?

这是一个相当长的问题,所以让我们将其分解:

代码语言:javascript
复制
\)?\s*\(?

说“也许可以匹配一个接近的paren,然后可能是一些空格,然后可能是一个开放的paren”。我想这没问题,让我们来看看真正的问题:

代码语言:javascript
复制
([\w\s+\\/]+)

此捕获组必须至少匹配一个字符。如果匹配器在您的地址末尾看到“委内瑞拉”,它将急切地字符venezuel,然后需要用剩下的a来满足最后一个表达式。相反,尝试:

代码语言:javascript
复制
\)?\s*

然后将整个最终表达式设为可选,并将外部表达式设为非捕获:

代码语言:javascript
复制
(?:\(?([\w\s+\\/]+)\)?)?

最后的表达式是:

代码语言:javascript
复制
([\w\s]*\w)(?:,\s*\(|,\s*|\s*\()([\w\s\\/]*\w)\)?\s*(?:\(?([\w\s+\\/]+)\)?)?

编辑:修复了一个问题,使最终的组捕获两次,一次与父母,一次没有。现在,它应该只捕获括号内的文本。

在您的示例中进行测试:

代码语言:javascript
复制
>>> 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')
票数 1
EN

Stack Overflow用户

发布于 2012-04-06 06:45:16

你能不能找出课文中的所有单词?

例如:

代码语言:javascript
复制
>>> 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']
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10036973

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档