Регулярное выражение для комментариев, но не внутри "строки" / не в другом контейнере - PullRequest
2 голосов
/ 09 февраля 2012

Так что мне нужно регулярное выражение для поиска однострочных и многострочных комментариев, но не в строке.(например, "my /* string")

для тестирования (# однострочная, /* & */ многострочная):

# complete line should be found
lorem ipsum # from this to line end
/*
  all three lines should be found
*/ but not here anymore
var x = "this # should not be found"
var y = "this /* shouldn't */ match either"
var z = "but" & /* this must match */ "_"

SO хорошо отображает синтаксис;Я в основном хочу весь серый текст.
Мне все равно, будет ли это одно регулярное выражение или два.;)

РЕДАКТИРОВАТЬ: еще одна вещь.противоположное также удовлетворило бы меня, ища строку, которой нет в комментарии
это мое текущее соответствие: "[\s\S]*?(?<!\\)" (действительно: не будет работать с "\\")

EDIT2:
ОК, наконец, я написал свой собственный анализатор комментариев -.-
И если кто-то еще заинтересован в исходном коде, возьмите его отсюда: https://github.com/relikd/CommentParser

Ответы [ 2 ]

6 голосов
/ 09 февраля 2012

Вот одна возможность (у нее есть ахиллесова пята, к которой я доберусь):

(#[^"\n\r]*(?:"[^"\n\r]*"[^"\n\r]*)*[\r\n]|/\*([^*]|\*(?!/))*?\*/)(?=[^"]*(?:"[^"]*"[^"]*)*$)

В действии здесь

С флагами GLOBAL и DOTALL, но не флаг MULTILINE.

Объяснение регулярного выражения:

(
  #[^"\n\r]*                         Hash mark followed by non-" and non-end-of-line
    (?:"[^"\n\r]*"[^"\n\r]*)*        If any quotes in the comment, they must be balanced
    [\r\n]                           Followed by end-of-line ($ except we 
                                      don't have multiline flag)

  |                                  OR
  /\*([^*]|\*(?!/))*?\*/             /* xxx */ sort of comment
  )                                  BOTH FOLLOWED BY
(?=[^"]*(?:"[^"]*"[^"]*)*$)           only a *balanced* number of quotes for the 
                                      *rest of the code :O!*

Однако, это полагается на сбалансированные кавычки, используемые по всему тексту (он также не учитывает экранированные кавычки, но достаточно легко изменить регулярное выражение, чтобы учесть это).

Если у пользователя есть комментарий с «в нем, который не сбалансирован ... бум. Вы облажались!

Регулярное выражение обычно не рекомендуется, например, при разборе HTML / кода, но если вы можете полагаться на тот факт, что кавычки должны уравновешиваться при определении строки и т. Д., Иногда вы можете сойти с рук.

Поскольку вы также анализируете комментарии , у которых нет заданной структуры (т.е. вы не гарантированы, что кавычки в комментариях будут сбалансированы), вы не сможете найти решение регулярных выражений, которое работает здесь.

Все, что вы придумываете, может быть перехвачено неуравновешенной цитатой где-то в комментарии (скажем, комментарий был # remove all the " marks) или многострочными строками (где на данной строке могут быть несбалансированные кавычки).

Итог - вы можете сделать регулярное выражение, которое будет работать в большинстве случаев, но не для всех. Чтобы получить что-то водонепроницаемое, вам нужно написать код.

0 голосов
/ 09 февраля 2012

Я бы использовал для этого два регулярных выражения:

  1. /(\/\*.*?\/)|(#.+?$)/m, чтобы найти все комментарии, модификатор "m" должен включить многострочный
  2. /"[^"]*?"/ чтобы найти все строки

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

...