为什么我的Regex(在php)不工作


Why does my Regex (in php) not work?

$data是一个包含大量锚文本(链接)的HTML文本

$regex = '/'b<a/i';
$data = '<a href="#">test</a> <a href="#">test 2</a>';
preg_match_all($regex, $data, $matches);

不返回,但是$data有两个<a

$regex = '/'b</i';

返回如预期的大量'<'

$regex = '/'ba/i';

返回很多'a',但是

$regex = '/'b<a/i';

返回什么。

为什么?

除了不使用DOM解析器之外,这里的问题是使用'b,因为它基本上匹配"类词"字符与非"类词"字符之间的转换,即

(?<='W)(?='w)|(?<='w)(?='W)

在这种情况下,只有<前面有一个字母才会匹配'b,例如:

foo<a

也许更好的表达方式是:

'/(?<='s|>)<a/i'

或者,甚至只是这个:

'/<a/i'

如果您只想匹配<a ....

这应该足够了。/<a/i

$data = "<a>Link 1</a> <a>Link 2</a> <a>Link 3</a>";
$regex =  '/<a/i'; //also will match <A in <A>Text</A>
preg_match_all($regex, $data, $matches);
var_dump($matches); //
/*
array (size=1)
  0 => 
    array (size=3)
      0 => string '<a' (length=2)
      1 => string '<a' (length=2)
      2 => string '<a' (length=2)
*/

$regex = '/'b

'b称为字边界。当一边是"单词字符"(字母、数字或下划线),而另一边不是单词字符时,它会匹配。

当您尝试在text <a...中匹配<a时,<左侧没有单词边界:

  • 左边是<(不是单词字符)
  • 右边是一个空格(不是单词字符)。
参考:

  • 单词边界