正则表达式反向引用问题

9

我使用

(?<!value=\")##(.*)##

要匹配类似于##MyString##这样的字符串,但不是以下形式:

<input type="text" value="##MyString##">

这适用于上述表单,但不适用于这个表单:(它仍然匹配,不应该匹配)
<input type="text" value="Here is my ##MyString## coming..">

我尝试过:

(?<!value=\").*##(.*)##

没有成功。非常感谢您提出的任何建议。

编辑:我正在使用PHP preg_match()函数


1
不要使用正则表达式来解析HTML - 使用HTML解析器。https://dev59.com/X3I-5IYBdhLWcg3wq6do#1732454 - Mark Byers
我正在使用它来替换HTML代码中的某些文本,因此preg_match对我来说是可以的。我不需要一个HTML解析器。 - Ali Selcuk
2
马克,我明白了。不要使用正则表达式解析HTML。但是如果用户不是试图解析HTML,而是在HTML中搜索特定字符串怎么办?难道真的需要使用XML解析器解析整个文档才能完成这项工作吗?我觉得很多人都用这个答案回答正则表达式问题,但实际上这并不是正确的答案。 - Mike Sherov
1
@Paul:我不是“每个人”。我不是毫无思考地说这话。我是因为我认为正则表达式是解决这个问题的一个糟糕方式而这样说的。如果你认为可以用正则表达式轻松解决问题,请展示一下怎么做吧 :) - Mark Byers
请记住,如果您打算处理现实世界中不能控制的HTML(例如带有Unicode的HTML5),那么解析HTML要比仅使用DOMDocument困难得多...在这种情况下应该使用html5lib(但它仍处于alpha版本)。 - Timo Huovinen
显示剩余9条评论
3个回答

4

这并不是完美的(这就是HTML解析器存在的原因),但它将适用于绝大多数HTML文件:

(^|>)[^<>]*##[^#]*##[^<>]*(<|$)

这个想法很简单。你正在寻找一个不在标签内的字符串。要不在标签内,最接近它的前一个尖括号必须是关闭的(或者根本没有括号),而最接近的后一个尖括号必须是打开的(或者没有)。这假设尖括号不用于属性值。
如果您实际上关心属性名为"value",那么可以匹配以下内容:
value\s*=\s*"([^\"]|\\\")*##[^#]*##([^\"]|\\\")*\"

... 然后只需否定匹配 (!preg_match(...))。


1

@楼主,你可以简单地不使用正则表达式来完成它。

$text = '<input type="text" value="   ##MyString##">';
$text = str_replace(" ","",$text);
if (strpos($text,'value="##' ) !==FALSE ){
    $s = explode('value="##',$text);
    $t = explode("##",$s[1]);
    print "$t[0]\n";
}

我认为这里有太多的开销。当需要替换50个字符串时,它将消耗太多的资源。而且,并不总是在##MyString##之前有空格,可能是任何字符。 - Ali Selcuk
如果在“##Mystring##”之前有除了空格以外的任何内容,则不应匹配,符合您的标准,对于开销,除非进行一些基准测试,否则无法确定。 - ghostdog74
@Dali 更多的代码并不意味着更多的开销,这个解决方案在某些情况下甚至可能比正则表达式更快,在其他情况下则可能更慢,就像ghostdog74所说的那样,你需要实际尝试一下。 - Timo Huovinen

0

至少这是一个起点,它适用于给定的示例。

(?<!<[^>]*value="[^>"]*)##(.*)##

警告:preg_match():编译失败:回顾断言不是固定长度 - Mark Byers
它报错:"Compilation failed: lookbehind assertion is not fixed length at offset 23",我正在使用PHP的preg_match函数。 - Ali Selcuk
@mark,我认为现在只有.NET引擎支持这种回顾后发现!我承认在任何其他语言中,这个问题实际上是非常具有挑战性的,我的观点并不是特别针对你,事实上在这种情况下你可能是正确的,但我仍然认为很多人跟风而行,却不理解其中的道理。 - Paul Creasey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接