【发布时间】:2018-03-27 13:08:30
【问题描述】:
我很难弄清楚我的regex 子模式中的编号到底是什么。我收到了PHP 警告:
PHP Warning: preg_replace_callback(): Compilation failed: different names for subpatterns of the same number are not allowed
尝试以下操作时:
$input = "A string that contains [link-ssec-34] and a [i]word[/i] here";
$matchLink = "\[link-ssec-(0?[1-9]|[1-9][0-9]|100)\]";
$matchItalic = "\[i](.+)\[\/i]";
$output = preg_replace_callback(
"/(?|(?<link>$matchLink)|(?<italic>$matchItalic))/",
function($m) {
if(isset($m['link'])){
$matchedLink = substr($m['link'][0], 1, -1);
//error_log('m is: ' . $matchedLink);
$linkIDExplode = explode("-",$matchedLink);
$linkHTML = createSubSectionLink($linkIDExplode[2]);
return $linkHTML;
} else if(isset($m['italic'])){
// TO DO
}
},
$input);
如果我删除命名的捕获组,如下所示:
"/(?|(?:$matchLink)|(?:$matchItalic))/"
没有警告,我得到了很好的匹配,但不能在我的函数中有条件地定位它们。我相信我正在遵循正确的程序来命名捕获组,但 PHP 说它们使用相同的 子模式编号,这是我迷失的地方,因为我不确定编号是什么。我熟悉使用 $1、$2 等处理子模式,但在与命名组一起使用时看不到这里的相关性。
目标
如果我使用了完全错误的技术,我应该包括我的目标。我最初使用preg_replace_callback() 来替换与这样的模式匹配的标记字符串:
$output = preg_replace_callback(
"/\[link-ssec-(0?[1-9]|[1-9][0-9]|100)\]/",
function($m) {
$matchedLink = substr($m[0], 1, -1);
$linkIDExplode = explode("-",$matchedLink);
$linkHTML = createSubSectionLink($linkIDExplode[2]);
return $linkHTML;
},
$input);
需求已经发展到需要匹配同一段落中的多个标签(我的原始示例包括下一个 [i]word[/i]。我不是从头开始为每个模式解析整个字符串,而是尝试查找所有单次扫描段落/字符串中的模式,相信它对系统的负担会更少。研究它使我相信在branch reset中使用命名的捕获组是最好的方法能够使用条件语句定位匹配项。也许我在这条路上走错了路,但希望能找到更好的方法。
想要的结果
$input = "A string that contains [link-ssec-34] and a [i]word[/i] here";
$output = "A string that contains <a href='linkfromdb.php'>Link from Database</a> and a <span class='italic'>word</span> here."
可以根据需要以包含单词或自包含的方括号格式添加更多模式。
【问题讨论】:
-
为什么你使用branch reset
(?|使用(?:非捕获组,或者在不需要时删除外部组。 -
@bobblebubble 为了清楚起见,我在编辑中添加了我的理解
-
@biscuitstack 你已经添加了你的 goal 但你从来没有真正定义过最终目标是什么(你基本上已经指出你的最终过程是什么以及你的问题的前提,但不是最终结果)。你到底想用
[link-ssec-XX]和[i][/i]来做什么?您是否以某种方式编辑原始字符串?如果是,输出是什么样的? -
@biscuitstack 我认为您的结果中有错字。你的意思是
<span class="italic">word</span>? -
@ctwheels 我的示例表明我需要区分
[link-ssec-XX]或[i]word[/i]是否匹配,而 (a) 替换匹配的内容 (b) 需要回调以使用匹配模式的部分, (c) 在系统开销方面尽可能高效,而不是运行多个preg_replace_callback()函数。我将任何匹配的字符串转换为无关紧要的内容,并且可能会使问题变得臃肿,但我这样做只是为了以防万一。见编辑。谢谢。
标签: php regex preg-replace-callback