【问题标题】:Regular expression lookbehind problem正则表达式后视问题
【发布时间】:2010-02-06 13:19:25
【问题描述】:

我用

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

匹配 ##MyString## 之类的字符串,但格式不是:

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

这适用于上述形式,但不适用于此:(它仍然匹配,不应该匹配)

<input type="text" value="Here is my ##MyString## coming..">

我试过了:

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

没有运气。任何建议将不胜感激。

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

【问题讨论】:

  • 不要使用正则表达式来解析 HTML - 使用 HTML 解析器。 stackoverflow.com/questions/1732348/…
  • 我用它来替换 HTML 代码中的某些文本,所以 preg_match 对我来说没问题。我不需要 HTML 解析器
  • 马克,我明白了。不要使用正则表达式解析 HTML。但是,如果用户不尝试解析 HTML,而是在 HTML 中搜索特定字符串怎么办?真的有必要使用 XML 解析器解析整个文档来完成这项工作吗?我觉得很多人都在用这个答案来回答正则表达式问题,而实际上它不是正确的答案。
  • @Mike,我完全同意,每个人似乎都在不假思索地重复“没有 HTML 的正则表达式”的言论。
  • @Paul:我不是“所有人”。我不是不假思索就这么说的。我这么说是因为我认为正则表达式是解决这个问题的糟糕方法。如果您认为使用正则表达式可以轻松完成,请展示如何操作。 :)

标签: regex lookbehind


【解决方案1】:

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

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

这个想法很简单。您正在寻找标签之外的字符串。要在标签之外,最靠近它的前面的尖括号必须是关闭的(或者根本没有括号),并且最近的后面的一个必须是打开的(或没有)。这假定属性值中不使用尖括号。

如果您真的关心属性名称是“值”,那么您可以匹配:

value\s*=\s*"([^\"]|\\\")*##[^#]*##([^\"]|\\\")*\"

...然后简单地否定匹配(!preg_match(...))。

【讨论】:

    【解决方案2】:

    @OP,你可以不用正则表达式就可以做到。

    $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## 之前并不总是空格,它可能是任何东西
    • 如果它在 ##Mystring## 之前只有空格,那么根据您的标准,它不应该匹配吗?至于开销,除非您进行一些基准测试,否则无法判断。
    • @Dali 更多代码并不意味着更多开销,这种解决方案在某些情况下甚至可能比正则表达式更快,而在另一些情况下则更慢,正如 ghostdog74 所说,您需要实际尝试一下。
    【解决方案3】:

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

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

    【讨论】:

    • 警告:preg_match():编译失败:后向断言不是固定长度
    • 它失败并显示“编译失败:lookbehind assertion is not fixed length at offset 23”我正在使用 PHP preg_match 函数
    • @mark,我认为.net 是唯一支持这种后视的引擎,现在你提到它!我承认这个问题实际上在任何其他语言中都非常具有挑战性,我上面的观点并不是专门针对你的,事实上你在这种情况下可能是对的,但我仍然说很多人在不理解的情况下跳入了bandwangon。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-09
    • 1970-01-01
    • 2011-01-25
    相关资源
    最近更新 更多