正则表达式选择上一次出现

时间:2014-04-11 17:34:37

标签: regex

我正在尝试从具有以下格式的字符串中提取City元素:

<BR>Address 1<BR>Address 2<BR>City<BR>A1A 0A0<BR>Phone Number <BR>

OR

<BR>Address 1<BR>Address 2<BR>Address 3<BR>City<BR>A1A 0A0<BR>Phone Number <BR>

输入字符串可以在城市之前具有随机数量的地址项。

到目前为止,我的策略是选择邮政编码(A1A 0A0),然后使用<BR>作为标记提取上一条记录。

到目前为止我正在使用

<BR>(.*)<BR>[ABCEFGHJKLMNPRSTVXY][0-9][ABCEFGHJKLMNPRSTVWXYZ] [0-9][ABCEFGHJKLMNPRSTVWXYZ][0-9]
$1

$ 1返回我正在使用的工具中的第一组正则表达式(visual web ripper)。然而,表达式返回邮政编码之前的所有内容。

那么有没有办法让正则表达式非贪婪选择以前的出现?

2 个答案:

答案 0 :(得分:2)

所以请耐心等待我,this is how我让它发挥作用:

(?:<BR>(.*?))+<BR>[ABCEFGHJKLMNPRSTVXY][0-9][ABCEFGHJKLMNPRSTVWXYZ] [0-9][ABCEFGHJKLMNPRSTVWXYZ][0-9]

说明:

(?:       # Start a non-capturing group (so that we don't have unnecessary matches)
  <BR>    # Look for a <BR> to start the group
  (.*?)   # Then lazily match 0+ characters (lazy will stop us at the next match)
)+        # End the group and repeat it 1+ times (each field)
<BR>      # Look for one final <BR> right before the Zip Code
[...]     # I didn't feel like including the Zip Code logic you wrote :)

但是,根据您的语言,我建议拆分字符串并循环遍历它。 PHP中的示例:

$pieces = explode('<BR>', '<BR>Address 1<BR>Address 2<BR>Address 3<BR>City<BR>A1A 0A0<BR>Phone Number<BR>');
$count = count($pieces);

$city = null;
for($i = 1; $i < $count; $i++) {
    if(preg_match('/[ABCEFGHJKLMNPRSTVXY][0-9][ABCEFGHJKLMNPRSTVWXYZ] [0-9][ABCEFGHJKLMNPRSTVWXYZ][0-9]/', $pieces[$i])) {
        $city = $pieces[$i - 1];
        break;
    }
}

var_dump($city);
// string(4) "City"

答案 1 :(得分:1)

我有点想要它,但在这里:

[^>]*<BR>[ABCEFGHJKLMNPRSTVXY][0-9][ABCEFGHJKLMNPRSTVWXYZ] [0-9][ABCEFGHJKLMNPRSTVWXYZ][0-9]

编辑:如果要添加捕获或非捕获组,可以执行以下操作:

不捕获和邮政编码:

[^>]*(?:<BR>[ABCEFGHJKLMNPRSTVXY][0-9][ABCEFGHJKLMNPRSTVWXYZ] [0-9][ABCEFGHJKLMNPRSTVWXYZ][0-9])

捕捉城市:

([^>]*)<BR>[ABCEFGHJKLMNPRSTVXY][0-9][ABCEFGHJKLMNPRSTVWXYZ] [0-9][ABCEFGHJKLMNPRSTVWXYZ][0-9]

编辑2:

根据以下评论:仅在城市名称不包含“&gt;”时才有效字符