Мне нужно сопоставить и заменить некоторые комментарии. например:
$test = "the url is http://www.google.com";// comment "<-- that quote needs to be matched
Я хочу сопоставить комментарии вне кавычек и заменить любые "
в комментариях с помощью».
Я попробовал несколько шаблонов и различные способы их запуска, но не повезло.
Регулярное выражение будет запущено с javascript для соответствия php "//" комментариев
UPDATE: я взял регулярное выражение из borkweb ниже и изменил его. использовал функцию из http://ejohn.org/blog/search-and-dont-replace/ и придумал следующее:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script type="text/javascript"> function t_replace(data){ var q = {}, ret = ""; data.replace(/(?:((["'\/]*(("[^"]*")|('[^']*'))?[\s]*)?[\/\/|#][^"|^']*))/g, function(value){ q[key] = value; }); for ( var key in q ){ ret = q[key]; } var text = data.split(ret); var out = ret + text[1]; out = out.replace(/"/g,"""); out = out.replace(/'/g,"'"); return text[0] + out; } </script> </head> <body> <script type="text/javascript"> document.write(t_replace("$test = \"the url is http://www.google.com\";// c'o\"mment \"\"\"<-- that quote needs to be matched")+"<br>"); document.write(t_replace("$test = 'the url is http://www.google.com';# c'o\"mment \"\"\"<-- that quote needs to be matched")); </script> </body> </html>
он обрабатывает все комментарии строк за пределами одиночных или двойных кавычек. Есть ли способ оптимизировать эту функцию?
ОБНОВЛЕНИЕ 2: он не обрабатывает эту строку
document.write(t_replace("$test //= \"the url is http://www.google.com\"; //c'o\"mment \"\"\"<-- that quote needs to be matched")+"<br>");
Вы можете иметь регулярное выражение для одновременного совпадения всех строк и комментариев. Если это строка, вы можете заменить ее самим, без изменений, а затем обработать специальный случай для комментариев.
Я придумал это регулярное выражение:
"(\\[\s\S]|[^"])*"|'(\\[\s\S]|[^'])*'|(\/\/.*|\/\*[\s\S]*?\*\/)
Есть 3 части:
"(\\[\s\S]|[^"])*"
для сопоставления строк с двойными кавычками. '(\\[\s\S]|[^'])*'
для сопоставления одиночных кавычек. (\/\/.*|\/\*[\s\S]*?\*\/)
для сопоставления как однострочных, так и многострочных комментариев. Функция replace проверяет, соответствует ли соответствующая строка комментарию. Если это не так, не заменяйте. Если это так, замените "
и '
.
function t_replace(data){ var re = /"(\\[\s\S]|[^"])*"|'(\\[\s\S]|[^'])*'|(\/\/.*|\/\*[\s\S]*?\*\/)/g; return data.replace(re, function(all, strDouble, strSingle, comment) { if (comment) { return all.replace(/"/g, '"').replace(/'/g, '''); } return all; }); }
Тестовый забег:
Input: $test = "the url is http://www.google.com";// c'o"mment """<-- that quote needs to be matched Output: $test = "the url is http://www.google.com";// c'o"mment """<-- that quote needs to be matched Input: $test = 'the url is http://www.google.com';# c'o"mment """<-- that quote needs to be matched Output: $test = 'the url is http://www.google.com';# c'o"mment """<-- that quote needs to be matched Input: $test //= "the url is http://www.google.com"; //c'o"mment """<-- that quote needs to be matched Output: $test //= "the url is http://www.google.com"; //c'o"mment """<-- that quote needs to be matched
Должен признаться, это регулярное выражение заняло у меня некоторое время, чтобы сгенерировать … но я уверен, что это сделает то, что вы ищете:
<script> var str = "$test = \"the url is http://www.google.com\";// comment \"\"\"<-- that quote needs to be matched"; var reg = /^(?:(([^"'\/]*(("[^"]*")|('[^']*'))?[\s]*)?\/\/[^"]*))"/g; while( str !== (str = str.replace( reg, "$1"") ) ); console.log( str ); </script>
Вот что происходит в регулярном выражении:
^ # start with the beginning of the line (?: # don't capture the following ( ([^"'\/]* # start the line with any character as long as it isn't a string or a comment ( ("[^"]*") # grab a double quoted string | # OR ('[^']*') # grab a single quoted string )? # but...we don't HAVE to match a string [\s]* # allow for any amount of whitespace )? # but...we don't HAVE to have any characters before the comment begins \/\/ # match the start of a comment [^"]* # match any number of characters that isn't a double quote ) # end un-caught grouping ) # end the non-capturing declaration " # match your commented double quote
Цикл while в javascript просто находит / заменяет, пока он не сможет найти никаких дополнительных совпадений в данной строке.
Не забывайте, что комментарии PHP также могут принимать форму /* this is a comment */
который может быть разделен на несколько строк.
Этот сайт может заинтересовать вас:
http://blog.stevenlevithan.com/archives/mimic-lookbehind-javascript
Javascript не имеет встроенной поддержки lookbehind в своем регулярном выражении. То, что вы можете сделать, это начать в конце строки и оглянуться назад, чтобы захватить любые символы, которые следуют за точкой с запятой + опциональным пробелом + // Так что-то вроде:
;\w*\/\/(.+)$
Это может не захватить все.
Вы также можете захотеть проверить PHP-синтаксис Javascript (или других языков). Я думаю, что синтаксический анализатор кода Komodo Edit может быть написан в Javascript. Если это так, это может дать вам представление о том, как вырезать все, кроме комментариев, поскольку синтаксические проверки должны гарантировать, что код PHP действителен, комментарии и все такое. То же самое можно сказать о синтаксических переключателях цвета. Вот еще две ссылки:
http://ecoder.quintalinda.com/
http://www.webdesignbooth.com/9-useful-javascript-syntax-highlighting-scripts/
В дополнение к ответу @Thai, который я нашел очень хорошо, я хотел бы добавить немного больше:
В этом примере с использованием исходного регулярного выражения будет сопоставлен только последний символ кавычек: https://regex101.com/r/CoxFvJ/2
Поэтому я немного изменил, чтобы разрешить захват полного содержимого кавычек и дать более разговорчивый и общий пример контента: https://regex101.com/r/CoxFvJ/3
Итак, последнее регулярное выражение:
/"((?:\\"|[^"])*)"|'((?:\\'|[^'])*)'|(\/\/.*|\/\*[\s\S]*?\*\/)/g
Большое спасибо тайскому за разблокировку меня.