我有几个字符串,我需要从中提取块编号。块编号的格式类型为“第3块”,“松块”,“块2”和“块4号”。请注意,这只是格式类型,数字可能会更改。我在OR条件下添加了它们。
问题在于,有时正则表达式提取连接到其他内容的前一个单词,如“主相位块2”,这意味着我需要提取“块2”。使用re.search导致第一个结果出现,甚至存在“OR”的限制。
我想要的是添加异常或使用类似
的条件来调整我的正则表达式如果在“块”一词之前出现1或2位数字(如23,3,6,7等),则用“块”后面的字提取“块”。
例如:
string = "rmv clusters phase 2 block 1 , flat no 209 dev." #extract "block 1" and not "2 block".
如果“阶段,公寓或建筑物”的字词出现在“块”之前,则提取后面的字块(无论是数字还是单词)
例如:
string 2 = "sky line apartments block 2 chandra layout" #extract "block 2" and not "apartments block"
这就是我所做的。但我不知道增加条件。
p = re.compile(r'(block[^a-z]\s\d*)|(\w+\sblock[^a-z])|(block\sno\s\d+)')
q = p.search(str)
这是整个功能的一部分。
答案 0 :(得分:1)
>> import re
>>> string = "rmv clusters phase 2 block 1 , flat no 209 dev."
>>> string2 = "sky line apartments block 2 chandra layout"
>>> print re.findall(r'block\s+\d+', string)
['block 1']
>>> print re.findall(r'block\s+\d+', string2)
['block 2']
答案 1 :(得分:1)
为什么不写多个正则表达式?请参阅python3中的以下代码段
def getBlockMatch(string):
import re
p1Regex = re.compile('block\s+\d+')
p2Regex = re.compile('(block[^a-z]\s\d*)|(\w+\sblock[^a-z])|(block\sno\s\d+)')
if p1Regex.search(string) is not None:
return p1Regex.findall(string)
else:
return p2Regex.findall(string)
string = "rmv clusters phase 2 block 1 , flat no 209 dev."
print(getBlockMatch(string))
string = "sky line apartments block 2 chandra layout"
print(getBlockMatch(string))
输出:
['block 1']
['block 2']
答案 2 :(得分:1)
在Python 2.7和3.3上测试。
import re
strings = ("rmv clusters phase 2 block 1 , flat no 209 dev."
"sky line apartments block 2 chandra layout"
"foo bar 99 block baz") # tests rule 1.
以下是您所说的规则:
所以
regex = re.compile(r'''
(?:\d{1,2}\s)(block\s\w*) # rule 1
| # or
(?:(phase|apartment|building).*?)(block\s\w+) # rule 2
''', re.X)
found = regex.finditer(strings)
for i in found:
print(i.groups())
打印:
(None, 'phase', '1')
(None, 'apartment', '2')
('block baz', None, None)
如果找不到,则无组是默认值,因此,您可以选择偏好设置并允许快捷方式or
返回第一个(如果它非空),或者第二个if第一个是为空(即在Python的布尔上下文中计算为False)。
>>> found = regex.finditer(strings)
>>> for i in found:
... print(i.group(1) or i.group(3))
...
1
2
block baz
所以把这个东西放到一个简单的函数中:
def block(str):
regex = re.compile(r'''
(?:\d{1,2}\s)(block\s\w*) # rule 1
| # or
(?:(phase|apartment|building).*?)(block\s\w+) # rule 2
''', re.X)
match = regex.search(str)
if not match:
return ''
else:
return match.group(1) or match.group(3) or ''
用法:
>>> block("foo bar 99 block baz")
'block baz'
>>> block("sky line apartments block 2 chandra layout")
'block 2'