RegEx在另一个特定术语之后匹配OR之前的术语

时间:2016-04-21 09:50:41

标签: python regex

我正在使用此RegExpression在某种文本中寻找一个平方米术语:

([0-9]{1,3}[\.|,]?[0-9]{1,2}?)\s?m\s?[qm|m\u00B2]

效果很好。

现在,只有在之前的OR之后才能匹配这个东西,像“Wohnfläche”/“Wohnfl”/“Wfl”这样的字符串存在。换句话说:后一个术语是强制性的,但其位置不是。 为此编写一个RegEx一般不是问题,我的问题是如何编写它最优雅。目前我只看到一种方法:

^[.]*[Wohnfläche|Wohnfl|Wfl]([0-9]{1,3}[\.|,]?[0-9]{1,2}?)\s?m\s?[qm|m\u00B2]

新搜索,与'或'语句结合(我正在使用Python)

([0-9]{1,3}[\.|,]?[0-9]{1,2}?)\s?m\s?[qm|m\u00B2][.]*[Wohnfläche|Wohnfl|Wfl]$
丑陋,不是吗? ;)

2 个答案:

答案 0 :(得分:1)

在控制应用程序中指定逻辑连接,如(伪代码)<area-regex>.match(string) and <text-regex>.match(string)

这假设同一个字符串上的两个regexen的任何一对匹配将永远不会重叠(如果他们这样做,你会得到误报)。你的regexen符合这个要求。

请注意,文本上下文的正则表达式包含测试字符串以匹配开头或结尾的附加限制,而在非正式描述中,您只需要在区域规范之前或之后匹配。这种差异包含在下面代码中的pt vs pt_anchored中。

Python片段(未经测试):

import re
...
# pa:          <area_regex>
# pt:          <text_regex>
# pt_anchored: <text_regex>, anchored
#
pa          = re.compile ( r'([0-9]{1,3}[\.|,]?[0-9]{1,2}?)\s?m\s?[qm|m\u00B2]' )
pt          = re.compile ( r'[.]*[Wohnfläche|Wohnfl|Wfl]' )                         
pt_anchored = re.compile ( r'^[.]*[Wohnfläche|Wohnfl|Wfl]|[.]*[Wohnfläche|Wohnfl|Wfl]$' )

if pa.match(<teststring>) and pt.match(<teststring>):
    print 'Match found: '
else:
    print 'No match'
...

答案 1 :(得分:1)

你可以像这样使用交替:

import re
pat = re.compile(r'(?:Wohnfläche|Wohnfl|Wfl)\s*(\d{1,3}(?:[.,]\d{1,2})?)\s?m\s?(qm|m\u00B2)|(\d{1,3}(?:[.,]\d{1,2})?)\s?m\s?(qm|m\u00B2)\s*(?:Wohnfläche|Wohnfl|Wfl)')
strs = ["12,56m qm Wohnfläche", "14.54 mqm Wohnfl", "Wfl 134 m qm"]
for x in strs:
    m = pat.search(x)
    if m:
        if m.group(1): # First alternative found a match
            print("{}".format(m.group(1), " - ", m.group(2)))
        else:          # Second alternative "won"
            print("{}".format(m.group(3), " - ", m.group(4)))

检查哪个捕获组匹配。在两侧的正则表达式中可选择使用限制性字符串是不可能的,只会被忽略。

请参阅regex demo

IDEONE demo

EPStatement cepStatementRule3 = cepRule.createEPL("context PartitionByMacHeartRate "
                + "select * from pattern[every(HeartRate(heartrate > 160) "
                + "-> (timer:interval(5 min) "
                + "and not HeartRate(heartrate<=160)))]");
        cepStatementRule3.addListener(new rule3Listener());