簡體   English   中英

正則表達式:匹配所有行中的子字符串,除非子字符串位於注釋部分內

[英]Regex: Match a substring in all lines, except when the substring is inside a comment section

我來啦:

我正在編寫一個PHP應用程序,我有一個新的官方域名,現在所有的FAQ都在這里。 我腳本中的一些文件包含舊FAQ域的幫助鏈接,因此我想使用新域替換它們。 但是,我想保留鏈接到舊域的URL,只要它們位於注釋或注釋塊下面(我仍然使用舊域進行自我引用和其他文檔)。

所以,基本上,我想要實現的是一個正則表達式,它具有以下功能:

  1. 匹配所有行中example.com的所有匹配項*。
  2. 不匹配整行,只匹配example.com字符串。
    • 如果行以///*或“*”開頭,則不匹配該單行中的任何example.com實例(但是,如果注釋塊在打開它的同一行中關閉,則可能會出現問題)。

我經常寫這樣的塊評論:

/* text
 * blah 
 * blah
*/

這就是為什么我不想匹配“example.com”,如果它位於///*或“*”之后。

我想它會是這樣的:

^(?:(?!//|/\*|\s\*).?).*example\.com

但是這有一個問題:它匹配整行,而不僅僅是“example.com”(這會導致問題,主要是當兩個或多個“example.com”字符串在一行中匹配時)。

有人可以幫我修復我的正則表達式嗎? 請注意:它不一定是PHP正則表達式,因為我總是可以使用像grepWin這樣的工具來一次本地編輯所有文件。

哦, 請告訴我是否有辦法以某種方式概括塊注釋,例如:找到/*在找到*/之前不匹配example.com 那將非常有用。 是否有可能實現一般(非語言相關)正則表達式?

一個正則表達式只匹配example.com如果它不在評論部分內(但不關心行注釋,所以你必須單獨執行此操作):

$result = preg_replace(
    '%example\.com # Match example.com
    (?!            # only if it\'s not possible to match
     (?:           # the following:
      (?!/\*)      #  (unless an opening comment starts first)
      .            #  any character
     )*            # any number of times
     \*/           # followed by a closing comment.
    )              # End of lookahead
    %sx', 
    'newdomain.com', $subject);

我會使用某種標記器來區分評論和其他語言標記。

在處理PHP文件時,您應該使用PHP自己的tokenizer函數token_get_all

$tokens = token_get_all($source);

然后,您可以枚舉標記並按類型分隔標記

foreach ($tokens as &$token) {
    if (in_array($token[0], array(T_COMMENT, T_DOC_COMMENT, T_ML_COMMENT))) {
        // comment
    } else {
        // not a comment
        $token[1] = str_replace('example.com', 'example.net', $token[1]);
    }
}

最后,把一切都回到一起implode

對於您手邊沒有合適的標記器的其他語言,您可以編寫自己的小標記器:

preg_match_all('~/\*.*?\*/|//(?s).*|(example\.com)|.~', $code, $tokens, PREG_SET_ORDER);
foreach ($tokens as &$token) {
    if (strlen($token[1])) {
        $token = str_replace('example.com', 'example.net', $token[1]);
    } else {
        $token = $token[0];
    }
}
$code = implode('', $tokens);

請注意,這不會考慮任何其他令牌,如字符串。 因此,如果它出現在字符串中,而且還在“評論”中,則不會匹配example.com

'foo /* not a comment example.com */ bar'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM