代码之家  ›  专栏  ›  技术社区  ›  onassar

正则表达式:在不在文本区域的字符串中查找新行字符

  •  3
  • onassar  · 技术社区  · 14 年前

    嘿,所以我正在寻找一个正则表达式,它允许我基本上用任意字符(例如“xxx”)替换换行符,但前提是换行符不在textarea标记内。

    例如,以下内容:

    <strong>abcd
    efg</strong>
    <textarea>curious
    george
    </textarea>
    <span>happy</span>
    

    <strong>abcdxxxefg</strong>xxx<textarea>curious
    geroge
    </textarea>xxx<span>happy</span>
    

    有人知道我该从哪里开始吗?我对这里有点一无所知:( 谢谢你的帮助。

    4 回复  |  直到 14 年前
        1
  •  3
  •   Alan Moore Chris Ballance    14 年前

    我有,但你不会喜欢的。;)

    $result = preg_replace(
      '~[\r\n]++(?=(?>[^<]++|<(?!/?textarea\b))*+(?!</textarea\b))~',
      'XYZ', $source);
    

    匹配换行符后,lookahead会向前扫描,使用任何不是左尖括号的字符,或者任何不是左尖括号开头的字符 <textarea> </textarea> 标签。当它用完这些标签时,它看到的下一个东西必须是这些标签中的一个或字符串的结尾。如果是 </文本区域> 标记,这意味着在textarea元素中找到了换行符,因此匹配失败,并且不会替换该换行符。

    我在下面提供了一个扩展版本,您可以 see it an action on ideone

      $re=<<<EOT
    ~
    [\r\n]++
    (?=
      (?>
        [^<]++            # not left angle brackets, or
      |
        <(?!/?textarea\b) # bracket if not for TA tag (opening or closing)
      )*+
      (?!</textarea\b)    # first TA tag found must be opening, not closing
    )
    ~x
    EOT;
    
        2
  •  1
  •   Andrew    14 年前

    如果仍要使用regexp,可以尝试以下操作-在特殊标记中转义换行,删除换行,然后取消外观:

    <?php //5.3 syntax here
    
    //Regex matches everything within textarea, pre or code tags
    $str = preg_replace_callback('#<(?P<tag>textarea|pre|code)[^>]*?>.*</(?P=tag)>#sim',
        function ($matches) { 
             //and then replaces every newline by some escape sequence
             return str_replace("\n", "%ESCAPED_NEWLINE%", $matches[0]);
        }, $str);
    //after all we can safely remove newlines
    //and then replace escape sequences by newlines
    $str = str_replace(array("\n", "%ESCAPED_NEWLINE%"), array('', "\n"), $str);
    
        3
  •  0
  •   Hammerite    14 年前

    为什么要用正则表达式呢?为什么不使用一个非常简单的状态机来做呢?穿过绳子寻找开口 <textarea> 标签,在里面寻找结束标签。当遇到换行符时,根据当前是否在 <文本区域>

        4
  •  0
  •   Andy Lester    14 年前

    你所做的是解析HTML。不能用正则表达式分析HTML。