正则表达式上的调节

时间:2014-03-08 05:21:28

标签: python regex string conditional-statements

我有几个字符串,我需要从中提取块编号。块编号的格式类型为“第3块”,“松块”,“块2”和“块4号”。请注意,这只是格式类型,数字可能会更改。我在OR条件下添加了它们。

问题在于,有时正则表达式提取连接到其他内容的前一个单词,如“主相位块2”,这意味着我需要提取“块2”。使用re.search导致第一个结果出现,甚至存在“OR”的限制。

我想要的是添加异常或使用类似

的条件来调整我的正则表达式
  1. 如果在“块”一词之前出现1或2位数字(如23,3,6,7等),则用“块”后面的字提取“块”。

    例如:

    string = "rmv clusters phase 2 block 1 , flat no 209 dev." #extract "block 1" and not "2 block".
    
  2. 如果“阶段,公寓或建筑物”的字词出现在“块”之前,则提取后面的字块(无论是数字还是单词)
    例如:

    string 2 = "sky line apartments block 2 chandra layout" #extract "block 2" and not "apartments block" 
    
  3. 这就是我所做的。但我不知道增加条件。

     p = re.compile(r'(block[^a-z]\s\d*)|(\w+\sblock[^a-z])|(block\sno\s\d+)')
        q = p.search(str) 
    

    这是整个功能的一部分。

3 个答案:

答案 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.

以下是您所说的规则:

  1. 如果在单词" block"之前出现1或2位数字(如23,3,6,7等),则提取"阻止"用下面的单词" block"。
  2. 如果是字#34;阶段,公寓或建筑物"来之前"阻止",提取阻塞后的单词(无论是数字还是单词)。 *我推断你也想要单词块。
  3. 所以

    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'