Мне нужна помощь в расшифровке этого регулярного выражения из звездочек - PullRequest
0 голосов
/ 19 января 2012

Мне нужна помощь в расшифровке этого регулярного выражения из звездочек. Я не уверен, что это соответствует, но если кто-то даст мне подсказки или отправные точки.

HEADER_PATTERN = /
\A (
  (?m:\s*) (
   (\/\* (?m:.*?) \*\/) |
   (\#\#\# (?m:.*?) \#\#\#) |
   (\/\/ .* \n?)+ |
   (\# .* \n?)+
  )
 )+
/x

Ответы [ 2 ]

3 голосов
/ 19 января 2012
HEADER_PATTERN = /
\A (                             # Start of string
  (?m:\s*) (                     # Match optional whitespace
   (\/\* (?m:.*?) \*\/) |        # Either match /* (any characters, lazily) */
   (\#\#\# (?m:.*?) \#\#\#) |    # or ### (any characters, lazily) ###
   (\/\/ .* \n?)+ |              # or // (any characters except newlines) until optional newline (one or more)
   (\# .* \n?)+                  # or # (any characters except newlines) until optional newline (one or more)
  )
 )+                              # once or more
/x

(?m:...) позволяет точке внутри этого подвыражения также совпадать с символами новой строки, чего обычно нет.(Это специальность Ruby; почти все другие разновидности регулярных выражений используют для этого (?s:...))

Так что кажется, что это регулярное выражение соответствует блочным комментариям или комментариям строк в начале файла / строки.

2 голосов
/ 19 января 2012
\A

Привязка к началу строки

(

Запускает группу, которая оборачивает всю строку. Он заканчивается на )+, так что это соответствует 1 или более экземплярам.

(?m:\s*)

Включает многострочный флаг для этого атома и сопоставляет ноль или более символов «пробел» (например, пробел, вертикальная табуляция, горизонтальная табуляция, новая строка или возврат каретки). Я понятия не имею, почему они включают многострочный флаг здесь, так как это не влияет на \s escape.

(\/\* (?m:.*?) \*\/)

Первый бит \/ соответствует символу / (экранирован, потому что / является разделителем для регулярного выражения). \* соответствует символу *. Пробел можно игнорировать из-за модификатора x. Затем снова включается многострочный флаг для .*?, что делает . совпадением с новыми строками. ? здесь делает модификатор * нежадным, поэтому он соответствует любому символу, но только так мало, как требуется, чтобы остальная часть шаблона соответствовала. Затем следует * и /. Другими словами, он соответствует комментарию в стиле C (/* text */)

|

или

(\#\#\# (?m:.*?) \#\#\#)

Соответствует любому тексту, окруженному ###, например, ### something ###. Снова использование многострочного модификатора с . и не жадное совпадение, чтобы оно перестало совпадать, как только ### совпадет с чем-либо. Символы # экранированы из-за модификатора x.

|

или

(\/\/ .* \n?)+

Совпадение //, за которым следует любой текст, за которым следует необязательный перевод строки. Я думаю, что новая строка необязательна в случае, если это конец строки. Отсутствие модификатора multiline заставляет . не соответствовать символам новой строки. Это в основном соответствует //, за которым следует что угодно, вплоть до конца строки.

|
* * Или тысяча сорок-девять
(\# .* \n?)+

Совпадение #, за которым следует любой текст, за которым следует необязательный перевод строки. То же самое, что и в предыдущем шаблоне, но с использованием # вместо //. Обратите внимание, что предыдущий шаблон ### имеет приоритет, потому что он более ранний, поэтому, если текст соответствует шаблону ###, он не будет соответствовать этому.

И, наконец, все использует модификатор x, поэтому пробелы, символы новой строки и любой текст после # в шаблоне игнорируются (поэтому он записан в несколько строк). Это только для удобства чтения.

...