Подтвердить что ты не робот

Что означает (^?) * В этом регулярном выражении?

У меня есть это регулярное выражение:

^(^?)*\?(.*)$

Если я правильно понимаю, это разбивка того, что он делает:

  • ^ - начать сопоставление с начала строки
  • (^?) * - Я не знаю, но он хранит его в $1
  • \? - соответствует вопросительному знаку
  • (. *) $- соответствует чему угодно до конца строки

Итак, что означает (^?) *?

4b9b3361

Ответ 1

(^?) просто ищет буквенный символ ^. Символ ^ в шаблоне регулярного выражения имеет особое значение при использовании в качестве первого символа шаблона или первого символа в совпадении группировки []. При использовании за пределами этих двух позиций ^ интерпретируется буквально для поиска символа ^ во входной строке

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

Ответ 2

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

Интерпретируется как шаблон Lua, пример удивит долгого пользователя регулярного выражения, поскольку многие детали отличаются.

Образцы Lua описаны в PiL, и на первый взгляд они достаточно похожи на обычное регулярное выражение, чтобы вызвать путаницу. Наибольшие различия, вероятно, связаны с отсутствием оператора чередования |, скобки используются только для отметки захватов, квантификаторы (?, -, + и *) применяются только к классу символов или символов, а % - это escape-символ, а не \. Большой ключ к тому, что этот пример, вероятно, не был написан с учетом Lua, - это отсутствие символа кавычек Lua-шаблона %, примененного к любому (или, в идеале, всем) не-алфавитно-цифровым символам в строке шаблона, а также к подозрительному использованию из \?, который пахнет обычным регулярным выражением, чтобы соответствовать одному литералу ?.

Простой ответ на заданный вопрос: (^?)* не является рекомендуемой формой и будет соответствовать ^* или *, фиксируя присутствие или отсутствие каретки. Если бы это был предполагаемый эффект, я бы написал его как (%^?)%*, чтобы сделать это более ясным.

Чтобы понять, почему это так, позвольте взять шаблон и проанализировать его как шаблон Lua. Весь шаблон:

^(^?)*\?(.*)$

Отправленный в string.match(), он будет интерпретироваться следующим образом:

^ привязывает соответствие к началу строки.

( обозначает начало первого захвата.

^ не находится в начале шаблона или символьного класса, поэтому он соответствует буквенному символу ^. Для ясности это должно быть написано как %^.

? соответствует ровно нулю или одному из предыдущего символа.

) обозначает конец первого захвата.

* - это не то, что можно количественно определить, чтобы оно соответствовало буквальному символу *. Для ясности это должно быть написано как %*.

\ в шаблоне совпадает с самим собой, это не escape-символ в языке шаблонов. Тем не менее, это символ escape в Lull короткометражном литерале, что делает следующий символ неспецифичным для синтаксического анализатора строк, который в этом случае является спорным, потому что следующий ? не был особенным для него. Таким образом, если шаблон был заключен в двойные или одинарные кавычки, тогда \ будет поглощаться синтаксическим анализом строк. Если написано в длинной строке (как [[^(^?)*\?(.*)$]], обратная косая черта выживет в синтаксическом анализаторе строк, появится в шаблоне.

? соответствует ровно нулю или одному из предыдущего символа.

( отмечает начало второго захвата.

. соответствует любому символу вообще, фактически синоним класса [\000-\255] (помните, что в числовых экранах Lua в десятичном виде не восьмерично, как в C).

* с жадностью соответствует нулю или более предыдущего символа.

) обозначает конец второго захвата.

$ привязывает шаблон к концу строки.

Таким образом, он сопоставляет и фиксирует необязательный ^ в начале строки, а затем *, а затем необязательный \, который не был захвачен, и фиксирует всю оставшуюся часть строки. string.match вернет две строки успеха (либо одна из них может быть нулевой длиной), либо nil при сбое.

Изменить: Я исправил некоторые опечатки и исправил ошибку в своем ответе, отмеченную Egor в комментарии. Я забыл, что в узорах специальные символы теряют свою особенность, когда в месте, где оно не может применяться. Это означает, что первая звездочка соответствует буквальной звездочке, а не ошибке. Каскад этого большинства проходит.

Обратите внимание, что если вы действительно хотите иметь правильное regexp в Lua, есть библиотеки, которые предоставят его. Тем не менее, встроенный язык шаблонов достаточно мощный. Если этого недостаточно, тогда вам может быть лучше всего использовать полный парсер и использовать LPeg, который может делать все регулярное выражение и Больше. Он даже поставляется с модулем, который предоставляет полный синтаксис regexp, который транслируется в грамматику LPeg для выполнения.

Ответ 3

В этом случае (^?) относится к предыдущей строке "^", что означает буквальный символ, как сказал Джаред. Проверьте regexlib для дальнейшего расшифровки.

Для всех потребностей Regex: http://regexlib.com/CheatSheet.aspx

Ответ 4

Мне кажется, что цель создателя выражения состояла в том, чтобы сопоставить любое число ^ перед вопросительным знаком, но хотелось только захватить первый экземпляр ^. Тем не менее, это может быть не допустимое выражение в зависимости от двигателя, как заявили другие.