【问题标题】:Trouble matching pattern at start or end with regex in Python在 Python 中使用正则表达式开始或结束匹配模式时遇到问题
【发布时间】:2015-10-08 18:59:08
【问题描述】:

我在使用 Python 正则表达式时遇到了困难。我想对 N、S、E、W、NB、SB、EB、WB 中的任何一个进行罚款,包括在字符串的开头或结尾。我的正则表达式很容易在中间找到它,但在开始或结束时都失败了。

谁能告诉我在代码示例下面的 dirPattern i 做错了什么?

注意:我意识到我还有一些其他问题需要处理(例如“W of”),但我认为我知道如何修改这些问题的正则表达式。

提前致谢。

import re

nameList = ['Boulder Highway and US 95 NB',  'Boulder Hwy and US 95 SB', 
'Buffalo and Summerlin N', 'Charleston and I-215 W', 'Eastern and I-215 S', 'Flamingo and NB I-15',
'S Buffalo and Summerlin', 'Flamingo and SB I-15', 'Gibson and I-215 EB', 'I-15 at 3.5 miles N of Jean',
'I-15 NB S I-215 (dual)', 'I-15 SB 4.3 mile N of Primm', 'I-15 SB S of Russell', 'I-515 SB at Eastern W',
'I-580 at I-80 N E', 'I-580 at I-80 S W', 'I-80 at E 4TH St Kietzke Ln', 'I-80 East of W McCarran',
'LV Blvd at I-215 S', 'S Buffalo and I-215 W', 'S Decatur and I-215 WB', 'Sahara and I-15 East',
'Sands and Wynn South Gate', 'Silverado Ranch and I-15 (west side)']

dirMap = {'N': 'North', 'S': 'South', 'E': 'East', 'W': 'West'}

dirPattern = re.compile(r'[ ^]([NSEW])B?[ $]')

print('name\tmatch\tdirSting\tdirection')
for name in nameList:
    match = dirPattern.search(name)
    direction = None
    dirString = None
    if match:
        dirString = match.group(1)
        if dirString in dirMap:
            direction = dirMap[dirString]
    print('%s\t%s\t%s\t%s'%(name, match, dirString, direction))

一些示例预期输出:

名称匹配dirSting方向

Boulder Highway 和 US 95 NB <_sre.sre_match object at> N North

Boulder Hwy 和 US 95 SB <_sre.sre_match object at> S South

Buffalo 和 Summerlin N <_sre.sre_match object at> N North

查尔斯顿和 I-215 W <_sre.sre_match object at> W West

Flamingo 和 NB I-15 <_sre.sre_match> N 北

S Buffalo 和 Summerlin <_sre.sre_match object at> S South

Gibson 和 I-215 EB <_sre.sre_match object at> E East

但是,开始或结束示例给出:

Boulder Highway 和 US 95 NB 无 无 无

【问题讨论】:

  • ^$ 在方括号内 并不仍然意味着字符串的开始/结束,你知道吗?
  • 乔恩,谢谢,我不知道,虽然我开始怀疑这一点。
  • 你到底想做什么?您也可以使用direction = dirMap.get(dirString),如果字典中没有匹配的键,它将返回None
  • Padraic,这是一个我不知道的好技巧。可以节省一些编码。从根本上说,m 问题是关于从样本字符串中提取键 N、S、E、W。我想要的是 N、NB 等,但只能单独使用,即要么在开头后跟空格,要么在结尾之前有空格,或者在中间有空格之前和之后。
  • 我的问题被否决的任何原因?我完全意识到这是一个相当新手的问题但是,我确实查看了之前的问题,并没有找到任何帮助。另外,我提供了工作代码示例。对我来说似乎很随意。

标签: python regex


【解决方案1】:

您需要使用lookarounds

dirPattern = re.compile(r'(?<!\S)([NSEW])B?(?!\S)')

[ ^] 将匹配空格或插入符号。 (?&lt;!\S)negative lookbehind 断言匹配之前会出现任何机器人而不是非空格字符。 (?!\S) 断言他的匹配后面不能跟非空格字符。

为什么我使用负前瞻而不是正方法,python 的默认 re 模块将不支持 (?&lt;=^| )

【讨论】:

  • 阿维纳什,感谢您的提示。当我在等待答案时,我开始使用环视来处理诸如“在 E 2nd St”或“W of I-15”之类的情况(两者都被排除在外。我想要的是 N、NB 等,但只能单独处理,即在开头后跟空格,在结尾前面有空格,或者在中间有空格之前和之后。你的回答可能会让我到达那里,但现在我不确定如何。
【解决方案2】:

这段代码中修改后的正则表达式可以解决问题。这包括处理诸如“W of”、“at E”之类的事情:

import re

nameList = ['Boulder Highway and US 95 NB',  'Boulder Hwy and US 95 SB', 
'Buffalo and Summerlin N', 'Charleston and I-215 W', 'Eastern and I-215 S', 'Flamingo and NB I-15',
'S Buffalo and Summerlin', 'Flamingo and SB I-15', 'Gibson and I-215 EB', 'I-15 at 3.5 miles N of Jean',
'I-15 NB S I-215 (dual)', 'I-15 SB 4.3 mile N of Primm', 'I-15 SB S of Russell', 'I-515 SB at Eastern W',
'I-580 at I-80 N E', 'I-580 at I-80 S W', 'I-80 at E 4TH St Kietzke Ln', 'I-80 East of W McCarran',
'LV Blvd at I-215 S', 'S Buffalo and I-215 W', 'S Decatur and I-215 WB', 'Sahara and I-15 East',
'Sands and Wynn South Gate', 'Silverado Ranch and I-15 (west side)']

dirMap = {'N': 'North', 'S': 'South', 'E': 'East', 'W': 'West'}

dirPattern = re.compile(r'(?:^| )(?<! at )(?<! of )([NSEW])B?(?! of )(?: |$)')

print('name\tdirSting\tdirection')
for name in nameList:
    match = dirPattern.search(name)
    direction = None
    dirString = None
    if match:
        dirString = match.group(1)
        direction = dirMap.get(dirString)
    print('> %s\t\t%s\t%s'%(name, dirString, direction))

正则表达式可以这样理解:

(?:^| ) 以字符串或空格开头

(?&lt;! at ) 前面没有'at'

(?&lt;! of ) 前面没有' of '

([NSEW]) 'N', 'S', 'E', 'W' 中的任意一个(这将在 match.group(1) 中)

B? 可选地后跟“B”(如绑定)

(?! of ) 后面没有'at'

(?: |$) 以字符串结尾或空格结尾

最终输出为:

博尔德高速公路和美国 95 NB N North

博尔德高速公路和美国 95 SB S 南

布法罗和萨默林 N N 北

查尔斯顿和 I-215 W W West

东部和 I-215 S S 南部

火烈鸟和 NB I-15 N 北

S Buffalo 和 Summerlin S South

火烈鸟和 SB I-15 S South

吉布森和 I-215 EB E 东

I-15 在 Jean None None 以北 3.5 英里处

I-15 NB S I-215(双)N 北

I-15 SB,Primm S South 以北 4.3 英里

Russell S South 的 I-15 SB S

位于东西南部的 I-515 SB

I-580 位于 I-80 N E N North

I-580 位于 I-80 S W S South

I-80 at E 4TH St Kietzke Ln 无 无

I-80 East of W McCarran 无 无

位于 I-215 S S South 的 LV 大道

S Buffalo 和 I-215 W S South

S Decatur 和 I-215 WB S South

撒哈拉和 I-15 East 无 无

金沙和永利南门 无 无

Silverado Ranch 和 I-15(西侧)无无

旁注:我决定不想要结束字符串大小写。为此,正则表达式为:

dirPattern = re.compile(r'(?:^| )(?&lt;! at )(?&lt;! of )([NSEW])B? (?!of )')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-06
    • 2012-07-11
    • 2016-02-06
    • 2012-04-14
    • 1970-01-01
    • 2020-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多