将连续的伪标记替换为具有共享样式的HTML标记

6jygbczu  于 2022-11-20  发布在  其他
关注(0)|答案(3)|浏览(106)

我有这条线

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]文本
在本文中有指定为a[...]的链接。在将来,我需要替换这些链接,并将其转换为以下形式:
链接1链接2链接3文本文本文本链接4文本链接5文本
前三个链接的类值为style1,文本后面的链接的类值为style2
在最开始的时候,在文本之前可以有三个链接,四个甚至一个,以及在文本之后可以有任何数量的链接,以任何顺序。

8wigbo56

8wigbo561#

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

a\[(\w+)\]

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

inb24sb2

inb24sb22#

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

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

说明

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

请参见regex demo

xxe27gdn

xxe27gdn3#

使用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

相关问题