6

我有两个句子作为输入。比如说:

<span>I love my red car.</span>
<span>I love my car.</span>

现在我想匹配跨度标签内的每个文本部分,如果有的话,颜色。

如果我使用以下正则表达式:

/<span>(.*?)(?P<color>red)(.*?)<\/span>/ms

只有与颜色匹配的线。所以我想让我们使用 ?-operator (一或零)。

/<span>(.*?)(?P<color>red)?(.*?)<\/span>/ms

现在两行/句子都将匹配。可惜颜色已经不匹配了。

问题是为什么?通过使用 ”。*?” 在颜色部分之前,我认为我已经使正则表达式不贪婪,以便颜色部分匹配,如果它存在的话。但正如所说,它不...

4

2 回答 2

5

第一个(.*?)将在 and 和 and 之间匹配>I因为它是惰性的,它会立即测试正则表达式的下一部分:(?P<color>red)?但那时还没有red,所以'activates'0选项?和正则表达式继续到下一部分,即(.*?). 它会再次匹配>andI和之间的部分,因为它是惰性的,它会检查正则表达式的下一部分:(<\/span>我把它作为一个整体)。

所以第二个(.*?)将一直匹配到那里。

事实上,你的results[1]will 是空的results[color](我不记得你是否必须引用color)并且results[3]将包含I love my red car..

嗯,一种解决方法是像 NickC 在他的回答中提到的那样使用 OR 。您可能会使用的另一个方法是使用负前瞻来检查每个字符:

<span>((?:(?!\bred\b).)*(?<colour>\bred\b)?.*)<\/span>

正则表达式101演示

作为旁注,我建议使用边界一词,这样您就不会匹配诸如reduceor之类的东西jarred

于 2013-09-18T07:35:08.190 回答
2

这应该有效:

/<span>(.*?(?P<color>red).*?|.*?)<\/span>/ms

你原来的表情还不错。我稍微修改了一下,使一个新的外部组匹配整个句子。我使用那个新的外部组来创建一个“或”条件来匹配“任何东西”,以防颜色不存在。

缩写输出:

Array
    [0] => Array
            [0] => <span>I love my red car.</span>
            [1] => <span>I love my car.</span>

    [1] => Array
            [0] => I love my red car.
            [1] => I love my car.

    [color] => Array
            [0] => red
            [1] => 
于 2013-09-18T07:30:57.347 回答