комментарии «//» с регулярным выражением, но не внутри цитаты

Мне нужно сопоставить и заменить некоторые комментарии. например:

$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,"&quot;"); out = out.replace(/'/g,"&apos;"); 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, '&quot;').replace(/'/g, '&apos;'); } 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&apos;o&quot;mment &quot;&quot;&quot;<-- 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 //= &quot;the url is http://www.google.com&quot;; //c&apos;o&quot;mment &quot;&quot;&quot;<-- 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&quot;") ) ); 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

Большое спасибо тайскому за разблокировку меня.