[英]Regex: Match a substring in all lines, except when the substring is inside a comment section
我來啦:
我正在編寫一個PHP應用程序,我有一個新的官方域名,現在所有的FAQ都在這里。 我腳本中的一些文件包含舊FAQ域的幫助鏈接,因此我想使用新域替換它們。 但是,我想保留鏈接到舊域的URL,只要它們位於注釋或注釋塊下面(我仍然使用舊域進行自我引用和其他文檔)。
所以,基本上,我想要實現的是一個正則表達式,它具有以下功能:
example.com
的所有匹配項*。 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.