Регулярное выражение для выбора конкретного содержимого, если оно не включено в комментарии

Я ищу регулярное выражение, которое соответствует шаблону src= "*. Js", но это не должно быть включено в комментарий.

рассмотрим следующее

<!------<script type="text/javascript" src="js/Shop.js"></script>  -->
<!----<script type="text/javascript" src="js/Shop.js"></script>  -->
<script type="text/javascript" src="jquery.serialize-object.js"></script>
<script type="text/javascript" src="jquery.cookie.js"></script>

Расширенный ввод проб, описанный OP как "правильный":

<!------<script type="text/javascript" src="js/Shop.js"></script>  -->
<!----<script type="text/javascript" src="js/Shop.js"></script>  -->
<script type="text/javascript" src="jquery.serialize-object.js"></script><!---->
<script type="text/javascript" src="jquery.serialize-object.js"></script><!-- a comment -- afterwards -->
<script type="text/javascript" src="jquery.serialize-object.js"></script><!-- a comment starting but not ending
-- afterwards -->
<script type="text/javascript" src="jquery.serialize-object.js"></script>
<script type="text/javascript" src="jquery.cookie.js"></script>

Результат не должен совпадать с строками 1 и 2 (где содержимое заключено в комментарии). Он должен соответствовать только строкам 3 и 4 (3-конец, за исключением строки конца комментария, для расширенного ввода образца).

Пока у меня есть это регулярное выражение, которое выбирает все мои.js файлы, а также те, которые закомментированы: (src=\")+(\S)+(.js)

Я ищу регулярное выражение, которое только выбирает теги скрипта с атрибутом.js src, которые не окружены комментарием.

Я также хотел бы упомянуть, что я использую это регулярное выражение в SQL-запросе Oracle PL.

Ответ 1

Я не знаю, можете ли вы делать то, что хотите, с одним регулярным выражением, тем более, что реализация регулярных выражений Oracle не поддерживает поиск. Но есть некоторые вещи, которые вы можете сделать с SQL, чтобы обойти эти ограничения. Следующие будут извлекать совпадения для шаблона, сначала удаляя комментарии из текста, а затем сопоставляя patter src=".*\.js" в том, что осталось. Несколько результатов извлекаются с помощью CONNECT BY:

SELECT html_id, REGEXP_SUBSTR(clean_html, 'src=".*\.js"', 1, LEVEL, 'i') AS match
  FROM (
    SELECT html_id, REGEXP_REPLACE(html_text, '<!--.*?-->', '', 1, 0, 'n') AS clean_html
      FROM (
        SELECT 1 AS html_id, '<!------<script type="text/javascript" src="js/Shop.js"></script>  -->
        <!----<script type="text/javascript" src="js/Shop.js"></script>  -->
        <script type="text/javascript" src="jquery.serialize-object.js"></script><!---->
        <script type="text/javascript" src="jquery.serialize-object.js"></script><!-- a comment -- afterwards -->
        <script type="text/javascript" src="jquery.serialize-object.js"></script><!-- a comment starting but not ending
        -- afterwards -->
        <script type="text/javascript" src="jquery.serialize-object.js"></script>
        <script type="text/javascript" src="jquery.cookie.js"></script>' AS html_text
          FROM dual
    )
)
CONNECT BY REGEXP_SUBSTR(clean_html, 'src=".*\.js"', 1, LEVEL, 'i') IS NOT NULL
   AND PRIOR html_id = html_id
   AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL;

Если эти результаты будут храниться в таблице где-нибудь, вы должны сделать следующее:

SELECT html_id, REGEXP_SUBSTR(clean_html, 'src=".*\.js"', 1, LEVEL, 'i') AS match
  FROM (
    SELECT html_id, REGEXP_REPLACE(html_text, '<!--.*?-->', '', 1, 0, 'n') AS clean_html
      FROM mytable
)
CONNECT BY REGEXP_SUBSTR(clean_html, 'src=".*\.js"', 1, LEVEL, 'i') IS NOT NULL
   AND PRIOR html_id = html_id
   AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL;

Кажется странным, но последние две строки необходимы, чтобы избежать дублирования результатов.

Результаты:

| HTML_ID | MATCH                              |
+---------+------------------------------------+
|       1 | src="jquery.serialize-object.js"   |
|       1 | src="jquery.serialize-object.js"   |
|       1 | src="jquery.serialize-object.js"   |
|       1 | src="jquery.serialize-object.js"   |
|       1 | src="jquery.cookie.js"             |
+---------+------------------------------------+

SQL Fiddle ЗДЕСЬ.

Надеюсь это поможет.

EDIT: Отредактировано в соответствии с моим комментарием ниже:

SELECT html_id, REGEXP_SUBSTR(clean_html, 'src="[^"]*\.js"', 1, LEVEL, 'i') AS match
  FROM (
    SELECT html_id, REGEXP_REPLACE(html_text, '<!--.*?-->', '', 1, 0, 'n') AS clean_html
      FROM (
        SELECT 1 AS html_id, '<!------<script type="text/javascript" src="js/Shop.js"></script>  -->
        <!----<script type="text/javascript" src="js/Shop.js"></script>  -->
        <script type="text/javascript" src="jquery.serialize-object.js"></script><!---->
        <script type="text/javascript" src="jquery.serialize-object.js"></script><!-- a comment -- afterwards -->
        <script type="text/javascript" src="jquery.serialize-object.js"></script><!-- a comment starting but not ending
        -- afterwards -->
        <script type="text/javascript" src="jquery.serialize-object.js"></script>
        <script type="text/javascript" src="jquery.cookie.js"></script>' AS html_text
          FROM dual
    )
)
CONNECT BY REGEXP_SUBSTR(clean_html, 'src="[^"]*\.js"', 1, LEVEL, 'i') IS NOT NULL
   AND PRIOR html_id = html_id
   AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL;

РЕДАКТИРОВАНИЕ

Если вы ищете CLOB а не столбец CHAR, первая строка предложения CONNECT BY должна выглядеть так. REGEXP_SUBSTR() вернет CLOB если соответствующий столбец CLOB, и сравнение в этом случае просто вечно:

CONNECT BY DBMS_LOB.SUBSTR(REGEXP_SUBSTR(clean_html, 'src="[^"]*\.js"', 1, LEVEL, 'i'), 4000, 1) IS NOT NULL

Надеюсь это поможет.

Ответ 2

Например, для ввода этого образца:

<!------<script type="text/javascript" src="js/Shop.js"></script>  -->
<!----<script type="text/javascript" src="js/Shop.js"></script>  -->
<script type="text/javascript" src="jquery.serialize-object.js"></script><!---->
<script type="text/javascript" src="jquery.serialize-object.js"></script><!-- a comment -- afterwards -->
<script type="text/javascript" src="jquery.serialize-object.js"></script><!-- a comment starting but not ending
-- afterwards -->
<script type="text/javascript" src="jquery.serialize-object.js"></script>
<script type="text/javascript" src="jquery.cookie.js"></script>

Это регулярное выражение: src="[^"]*\.js\"></script>(\s*<!--[^>]*-->)*(\s*<!--[^>]*)?$
даст вам этот результат:

<script type="text/javascript" src="jquery.serialize-object.js"></script><!---->
<script type="text/javascript" src="jquery.serialize-object.js"></script><!-- a comment -- afterwards -->
<script type="text/javascript" src="jquery.serialize-object.js"></script><!-- a comment starting but not ending
<script type="text/javascript" src="jquery.serialize-object.js"></script>
<script type="text/javascript" src="jquery.cookie.js"></script>

Я тестировал с GNU grep 2.5.4, надеясь, что он приблизится к вашему регулярному выражению. Регулярное выражение очень легкое по специальным функциям.

Объяснение:

  • \"[^"]* Есть "что - нибудь в " "
  • (<!--[^>]*-->)* - "любое количество полных комментариев, если они не содержат > "
  • (<!--[^>]*)?$ является необязательным началом комментария non- > в конце строки "
  • \s* разрешение дополнительного пробела

Обратите внимание, что в какой-то момент возможной сложности соответствующего ввода регулярные выражения перестают быть правильным инструментом. Помимо этого, выделенный инструмент, т.е. Синтаксический анализатор XML/html, является выбором.
Для меня эта точка достигается, когда возникает вероятность того, что соответствующий вход "скрыт" внутри многострочного комментария. Я чувствую, что вы включили этот вопрос в движущуюся цель, сначала подтвердив, что ожидание соответствующего ввода на одной строке разрешено (кроме комментария, начинающегося после этого), но затем изменило правила, добавив противоречивый ввод образца. В какой-то момент вы описали образец ввода, который я предложил как "правильный".
(Очень смешно) XML/регулярное выражение, обсуждающее QA, связанное в комментариях, демонстрирует, что вы, возможно, попадете в ад, если вы не нарисуете линию достаточно рано.
При ограничении в заданную среду, например SQL-сервер, особые возможности этой среды должны быть задействованы. Разумеется, обработка non- комментариев частей ввода с помощью механизмов SQL для достижения некоторых шагов может быть достигнута. Т.е. бросайте свое непосредственное представление о том, как действовать дальше и немного обдумывать мышление. Постарайтесь убедиться, что вы не исчерпаете себя проблемой XY.

Ответ 3

Я положил негативный взгляд вперед до конца вашего регулярного выражения, но помните, что если есть комментарий после src он также будет проигнорирован.

(src=\")+(\S)+(\.js\")+(?!.*-->)(.*)

Редактировать:

Мне удалось найти что-то похожее без lookahead (чего нет PL/SQL):

(src=\")(\S)+(\.js\")[^(--)\n]+(\n|$)

Ответ 4

Вот мое решение: один простой негативный взгляд.

(?<!<!--.+)src=".+\.js"

Это соответствует всем атрибутам src в расширенном примере, но не предшествующим <!--. Этого может быть достаточно, скажите, если я пропустил некоторые конкретные случаи;)

Вот мое решение работает в расширенном примере: https://regex101.com/r/rmHkbm/1

EDIT: Это работает в javascript, я не знаю, для ORACLE PL/SQL. Есть ли способ проверить его без установки базы данных Oracle?

Ответ 5

Я не думаю, что можно делать то, что вы хотите, используя одно регулярное выражение без негативного обратного просмотра. Но вы можете сделать это, логически комбинируя два похожих регулярных выражения таким образом, который легко сделать в SQL. Основная идея:

[MATCH_EXPR] AND NOT [COMMENTED_MATCH_EXPR]

Предположим, что у нас есть data таблицы со line столбца (строки кода), мы могли бы выбрать интересующие строки с чем-то вроде:

SELECT line
FROM data
WHERE REGEXP_LIKE(line, 'src="[^"]+.js"') AND NOT REGEX_LIKE(line, '<!--.*src="[^"]+.js"');

Вы можете обновлять регулярные выражения, чтобы быть более точными и/или делать с ними что-то более сложное, например, захватывать имена файлов, но подход будет таким же.

Этот подход не является пуленепробиваемым, поскольку он не сможет найти строки, которые состоят из двух операторов <script> где только второй будет закомментирован, так как будет соответствовать второе регулярное выражение. Тем не менее, это, вероятно, будет работать для подавляющего большинства типичного кода, включая приведенные выше примеры.

Ответ 6

Я попробовал следующее на https://livesql.oracle.com, так что, вероятно, сработает для вас. предполагая, что строка без комментирования начинается с '<script'. Он соответствует строкам типа

    <script type="text/javascript" src="jquery.cookie.js"></script>
    <script type="text/javascript" src="jquery.serialize-object.js"/>
    <script type="text/javascript" src="jquery.serialize-object.js"></script><!-- a comment -- afterwards -->

запрос с регулярными выражениями:

select "SRC" from "TABLE_1" 
where REGEXP_LIKE (SRC, '^\<script.+\.js.+script\>$') 
   or REGEXP_LIKE (SRC, '^\<script.+\.js.+script\>\<\!\-\-.+\-\-\>$') 
   or REGEXP_LIKE (SRC, '^\<script.+\.js.+\/\>$');