[英]Remove all REAL Javascript comments in PHP
我正在尋找一種使用 PHP 去除 HTML 代碼中所有javascript 注釋的解決方案。
我只想刪除Javascript 注釋(而不是 HTML 注釋等)。 我認為正則表達式不是解決方案,因為它無法理解是真正的注釋還是字符串的一部分。 例子:
<script>
// This is a comment
/* This is another comment */
// The following is not a comment
var src="//google.com";
</script>
有辦法嗎? 提前謝謝了
要做的第一件事:您需要提取腳本標簽的內容。 為此,請使用 DOMDocument:
$dom = new DOMDocument;
$dom->loadHTML($html);
$scriptNodes = $dom->getElementsByTagName('script');
第二步包括刪除每個腳本節點的所有 javascript 注釋。
如果需要,您可以使用第三方 javascript 解析器,但您也可以使用正則表達式來實現。 您所需要的只是防止將引號之間的部分考慮在內。
為此,您必須搜索引號之間的第一部分並丟棄它們。 使用 javascript 做到這一點的唯一困難是引號可以在正則表達式模式中,例如:
/pattern " with a quote/
所以你需要找到模式來防止任何錯誤。
圖案示例:
$pattern = <<<'EOD'
~
(?(DEFINE)
(?<squoted> ' [^'\n\\]*+ (?: \\. [^'\n\\]* )*+ ' )
(?<dquoted> " [^"\n\\]*+ (?: \\. [^"\n\\]* )*+ " )
(?<tquoted> ` [^`\\]*+ (?s: \\. [^`\\]*)*+ ` )
(?<quoted> \g<squoted> | \g<dquoted> | \g<tquoted> )
(?<scomment> // \N* )
(?<mcomment> /\* [^*]*+ (?: \*+ (?!/) [^*]* )*+ \*/ )
(?<comment> \g<scomment> | \g<mcomment> )
(?<pattern> / [^\n/*] [^\n/\\]*+ (?>\\.[^\n/\\]*)* / [gimuy]* )
)
(?=[[(:,=/"'`])
(?|
\g<quoted> (*SKIP)(*FAIL)
|
( [[(:,=] \s* ) (*SKIP) (?: \g<comment> \s* )*+ ( \g<pattern> )
|
( \g<pattern> \s* ) (?: \g<comment> \s* )*+
( \. \s* ) (?:\g<comment> \s* )*+ ([A-Za-z_]\w*)
|
\g<comment>
)
~x
EOD;
然后替換每個腳本節點的內容:
foreach ($scriptNodes as $scriptNode) {
$scriptNode->nodeValue = preg_replace($pattern, '$9${10}${11}', $scriptNode->nodeValue);
}
$html = $dom->saveHTML();
圖案詳情:
((?DEFINE)...)
是一個區域,您可以在其中放置稍后需要的所有子模式定義。 “真正的”模式在此之后開始。
(?<name>...)
是命名的子模式。 它與捕獲組相同,只是您可以使用其名稱(如\\g<name>
)而不是其編號來引用它。
*+
是所有格量詞
\\N
表示不是換行符的字符
(?=[[(:,=/"'
。目標這個測試的目的是為了防止在字符不同的情況下測試以下交替的每個分支。如果刪除它,模式將起作用,只是快速跳過字符串中無用的位置。])</code> is a [lookahead][3] that checks if the next character is one of these <code>[ ( : , = / " '
(*SKIP)
是一個回溯控制動詞。 當模式在它之后失敗時,在它之前匹配的所有位置都不會被嘗試。
(*FAIL)
也是一個回溯控制動詞並強制模式失敗。
(?|..(..)..(..)..|..(..)..(..)..)
是一個分支復位組。 在其中,捕獲組在每個分支中分別具有相同的編號(對於此模式為 9 和 10) 。
使用這個功能
function removeComments(str) { str = ('__' + str + '__').split(''); var mode = { singleQuote: false, doubleQuote: false, regex: false, blockComment: false, lineComment: false, condComp: false }; for (var i = 0, l = str.length; i < l; i++) { if (mode.regex) { if (str[i] === '/' && str[i-1] !== '\\') { mode.regex = false; } continue; } if (mode.singleQuote) { if (str[i] === "'" && str[i-1] !== '\\') { mode.singleQuote = false; } continue; } if (mode.doubleQuote) { if (str[i] === '"' && str[i-1] !== '\\') { mode.doubleQuote = false; } continue; } if (mode.blockComment) { if (str[i] === '*' && str[i+1] === '/') { str[i+1] = ''; mode.blockComment = false; } str[i] = ''; continue; } if (mode.lineComment) { if (str[i+1] === 'n' || str[i+1] === 'r') { mode.lineComment = false; } str[i] = ''; continue; } if (mode.condComp) { if (str[i-2] === '@' && str[i-1] === '*' && str[i] === '/') { mode.condComp = false; } continue; } mode.doubleQuote = str[i] === '"'; mode.singleQuote = str[i] === "'"; if (str[i] === '/') { if (str[i+1] === '*' && str[i+2] === '@') { mode.condComp = true; continue; } if (str[i+1] === '*') { str[i] = ''; mode.blockComment = true; continue; } if (str[i+1] === '/') { str[i] = ''; mode.lineComment = true; continue; } mode.regex = true; } } return str.join('').slice(2, -2); }
使用這兩個鏈接http://trinithis.awardspace.com/commentStripper/stripper.html
http://james.padolsey.com/javascript/removing-comments-in-javascript/
進一步參考檢查它Javascript 注釋剝離器
此 RegExp 將適用於您的示例:
^\/(?:\/|\*).*
PHP代碼:
$re = "/^\\/(?:\\/|\\*).*/m";
$str = "<script>\n\n// This is a comment\n/* This is another comment */\n\n// The following is not a comment\nvar src=\"//google.com\"; \n\n</script>";
preg_match_all($re, $str, $matches);
或者也許這個,以驗證*/
:
^\/{2}.*|\/\*.*\*\/$
PHP代碼:
$re = "/^\\/{2}.*|\\/\\*.*\\*\\/$/m";
$str = "<script>\n\n// This is a comment\n/* This is another comment */\n\n// The following is not a comment\nvar src=\"//google.com\"; \n\n</script>";
preg_match_all($re, $str, $matches);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.