regex PHP中的正则表达式搜索

lyfkaqu1  于 2022-11-18  发布在  PHP
关注(0)|答案(3)|浏览(147)

我有这条线

a[link], a[link] a [link] text text text a [link] text a[link] text

因此,我想找到文本之前的第一个链接,对它们进行一次操作,并以特殊的样式突出显示它们(在本例中,可能有三个或多或少),然后找到文本之后的其他链接,并以不同的样式突出显示它们。
我只能找到前三个链接,但我不知道我做得如何

<?php
$re = '/^(a\[(\w+[\s+]?)+\],?\s?)+/iu';
$str = 'a[link], a[link] a[link] text text text a[link] text a[link] text';
preg_match($re, $str, $matches, PREG_OFFSET_CAPTURE, 0);
var_dump($matches);
?>

我现在试着给予一个例子来说明需要做些什么:有这样一段文字
a[链接1],a[链接2] a[链接3]文本文本文本a[链接4]文本a[链接5]文本
在本文中有指定为[ ]的链接,在未来我需要替换这些链接,并将其带到此表单中
链接1链接2链接3文本文本文本链接4文本链接5文本
前三个链接有一个赋值为style1的类,文本后面的链接已经有一个赋值为style2的类。最开始,文本前面可以有三个链接,四个甚至一个,文本后面可以有任意数量的链接,顺序也不限。

qlfbtfca

qlfbtfca1#

不要试图一次匹配所有内容。单独匹配每个链接,然后遍历结果。使用preg_match_all,或者如果你想对每个匹配进行替换,使用preg_replace_callback

a\[(\w+)\]

应该能达到你的目的。
不清楚[\s+]?的目标是什么,是否允许使用空格或+。也不清楚链接后的可选逗号和空格。保持简单是最好的方法。
https://3v4l.org/2AvT1

yftpprvb

yftpprvb2#

在php中,你可以使用\G锚,然后使用2个捕获组来了解开头的行和其他链接之间的区别。

\Ga\h*\[([^][]*)],?\h*|\[([^][]*)]

说明

  • \G在字符串的开头或上一个匹配的结尾Assert当前位置
  • a\h*匹配a和可选的水平空白字符
  • \[([^][]*)]匹配[...]并在第1组中记录方括号之间的内容
  • ,?\h*匹配可选逗号和水平空格字符
  • |
  • \[([^][]*)]匹配[...]并在第2组中记录方括号之间的内容

请参见regex demo

hjqgdpho

hjqgdpho3#

使用preg_replace_callback()在一个整合的过程中捕获和替换所需的字符串。
在第一个撷取群组中使用包含右方大括号的Lookbehind,以区分连续序列的第一个相符项目与相同连续序列的后续成员。
第一个捕获组($m[1])将为null或空字符串
第二个捕获组($m[2])将是连续链接之间的粘附字符。
第三个撷取群组($m[3])将是链接的目的文字。
每次遇到组中第一个链接(空lookbehind)时,递增样式计数器。
代码:(Demo

$styleCounter = 0;
echo preg_replace_callback(
         '/((?<=]))?+(,? ?)a\[([^][]*)]/',
         function ($m) use(&$styleCounter) {
             if ($m[1] === null) {
                 ++$styleCounter;
             }
             return "{$m[2]}<a href=\"{$m[3]}\" class=\"style{$styleCounter}\">{$m[3]}</a>";
         },
         $string,
         -1,
         $count,
         PREG_UNMATCHED_AS_NULL
     );

图案:

/            #starting delimiter
((?<=]))?+   #greedily, optionally match the zero-width position where the previous character was a literal "]" as capture group 1 
(,? ?)       #match an optional comma followed by an optional space as capture group 2
a\[          #match a literal "a" then "[" 
([^][]*)     #match zero or more non-square-brace characters as capture group 3
]            #match a literal "]"
/            #ending pattern delimiter

相关问题