Сравнение шаблонов Lua и регулярных выражений

Я сейчас изучаю lua. относительно сопоставления с образцом в lua я нашел следующее предложение в документации lua на lua.org:

Тем не менее сопоставление с образцом в Lua является мощным инструментом и включает некоторые функции, которые трудно сопоставить со стандартными реализациями POSIX.

Поскольку я знаком с регулярными выражениями posix, я хотел бы знать, есть ли какие-нибудь общие примеры, в которых сопоставление с образцом lua «лучше» по сравнению с регулярным выражением - или я неправильно истолковал предложение? и если есть какие-то общие примеры: почему какое-либо сопоставление с образцом или регулярное выражение лучше подходит?


person aurora    schedule 22.04.2010    source источник
comment
ссылка на то, где вы это читаете, в документации было бы неплохо   -  person    schedule 11.02.2013
comment
@ g33kz0r документы доступны по адресу: lua.org/pil/20.1.html the цитата из второго абзаца (тот, который начинается с: В отличие от некоторых других языков сценариев, ...) последнего предложения.   -  person aurora    schedule 11.02.2013


Ответы (4)


Есть ли какие-нибудь общие примеры, в которых сопоставление с образцом lua «лучше» по сравнению с регулярным выражением?

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

Вот несколько факторов, которые способствуют хорошему дизайну:

  • Очень легкий синтаксис для сопоставления общих типов символов, включая прописные буквы (%u), десятичные цифры (%d), пробелы (%s) и т. Д. Любой тип символа может быть дополнен соответствующей заглавной буквой, поэтому шаблон %S соответствует любому непробельному символу.

  • Цитирование очень простое и регулярное. Знак кавычек - %, поэтому он всегда отличается от символа кавычек в строке \, что значительно упрощает чтение шаблонов Lua, чем регулярные выражения POSIX (когда кавычки необходимы). Всегда безопасно заключать символы в кавычки, и никогда не нужно заключать в кавычки буквы, поэтому вы можете просто следовать этому практическому правилу, вместо того, чтобы запоминать, какие символы являются специальными метасимволами.

  • Lua предлагает «захваты» и может возвращать несколько захватов в результате match вызова. Этот интерфейс намного, намного лучше, чем захват подстрок с помощью побочных эффектов или наличие какого-то скрытого состояния, которое нужно опросить, чтобы найти захваты. Синтаксис захвата прост: используйте круглые скобки.

  • В Lua есть модификатор «самого короткого совпадения» -, который следует за оператором «самого длинного совпадения» *. Так, например, s:find '%s(%S-)%.' находит кратчайшую последовательность непробельных символов, которой предшествует пробел и за которой следует точка.

  • Выразительная сила шаблонов Lua сравнима с «базовыми» регулярными выражениями POSIX без оператора чередования |. Вы отказываетесь от "расширенных" регулярных выражений с |. Если вам нужна такая выразительная мощь, я рекомендую полностью перейти на LPEG что дает вам, по сути, мощь контекстно-свободных грамматик по вполне разумной цене.

person Norman Ramsey    schedule 23.04.2010
comment
спасибо - много информации. Я думаю, что мне нужно глубже вникнуть в сопоставление с образцом lua, прежде чем я полностью пойму, что было с процитированным предложением ... - person aurora; 26.04.2010
comment
Разве модификатор кратчайшего совпадения не то же самое, что оператор экономного сопоставления PCRE *? ? - person b0fh; 22.08.2011
comment
Также есть %bxy, который соответствует сбалансированной паре разделителей, например круглой или фигурной скобке. Сбалансированное сопоставление скобок невозможно в регулярных выражениях POSIX. Кроме того, существует шаблон границ, который присутствует, но недокументирован в Lua 5.1, и становится документированной функцией в 5.2. В вики говорится Граничный шаблон %f, за которым следует набор, определяет переход от не установленного к внутреннему set Эта операция возможна, но в регулярном выражении она намного более подробна. - person RBerteig; 25.08.2011
comment
(Этот пост увековечен как лучший результат для google.com/search?q= lua + decimal + regex, где я пришел, чтобы узнать, что делать, когда \ d не сработал. Хорошо, чтобы сэкономить следующему человеку полшага к решению. [Спасибо, что написали этот пост, чтобы сделать большую часть работы.]) - person misterbee; 22.08.2012
comment
В Lua модификаторы *, +, - и? может применяться только к классу символов. Хотел бы я сгруппировать шаблоны по модификатору. Например, '(xx) * x' будет соответствовать нечетному количеству x. У меня есть приложение, которое позволяет пользователям выполнять поиск по строкам шаблонов Lua. Я хотел бы иметь возможность изменить их шаблон, чтобы сделать его нечувствительным к регистру. Таким образом, "%% ab% ac %%% a" станет "%% [aA] [bB]% a [cC] %%% a". Здесь будет полезна возможность поиска четного числа escape-символов ('%'). Что-то вроде p = str: gsub ((%%%%) *% a, function (a, b) return string.format (% s [% s% s], a, b: lower (), b: upper ( ))) конец) - person Stomp; 15.11.2012
comment
Имейте в виду, что у вас нет Unicode. Шаблоны Lua совпадают по байтам. Если вы используете многобайтовую кодировку, будьте очень осторожны. - person David Given; 15.08.2015
comment
Помимо того, что указано в спецификациях Lua, единственными эффективными преимуществами, которые предлагают шаблоны Lua, являются% bXY для сопоставления пар (путем добавления дополнительного счетчика в конечный автомат) и для% f [set] границ (дополнительные типы привязок). - person verdy_p; 24.10.2018
comment
Все остальное полностью покрыто регулярными выражениями POSIX. Я не вижу реального преимущества использования '%' вместо '\', когда Lua также имеет собственное использование '\' для экранирования, что также создает еще большую путаницу, если вам нужно записать его как% \\ или если вы все еще нужно, чтобы% перед \ 045, или \ x2D, или \ u {002D} соответствовали только литеральной точке, но НЕ ДОЛЖНЫ использовать% перед \ d091, или \ x61, или \ x {0061}, чтобы соответствовать только литеральному 'a')!) - person verdy_p; 24.10.2018
comment
Также второстепенным преимуществом является то, что для его реализации на C требуется всего ~ 500 строк кода по сравнению с ~ 4000 для полных регулярных выражений POSIX (но гораздо меньше, если все, что вам нужно, это добавить критически отсутствующую функцию |). Эти дополнительные строки исходного кода не создают большого количества двоичного кода, и регулярные выражения POSIX уже реализованы и используются в той же системе. Эта дополнительная стоимость в движке очень мала (по сравнению с потребностями в памяти для самого базового движка Lua и его стандартной библиотеки по умолчанию). Но это экономит затраты разработчиков Lua на выполнение тестов покрытия. - person verdy_p; 24.10.2018

http://lua-users.org/wiki/LibrariesAndBindings содержит список функций, включая библиотеки регулярных выражений. если вы хотите продолжать их использовать.

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

[Edit] Я только что нашел в онлайн-версии Programming in Lua (отличный ресурс для изучения языка), где это описано одним из принципов языка: см. Комментарии ниже [/ Edit]

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

person Keith Pimmel    schedule 22.04.2010
comment
хорошо - я думал, дело не только в размере. Я читал, что библиотека сопоставления с образцом lua имеет размер около 500 локусов по сравнению с библиотеками регулярных выражений с ~ 4000 локусов - это круто, но я думал, что это также связано с удобством: я много делаю с регулярным выражением, и я знаю, что этот материал может становится очень сложным и запутанным - так что: есть ли какие-либо другие функции, которые делают сопоставление с образцом lua более удобным или простым в использовании или ... чем posix regexp - помимо loc? пожалуйста, имейте в виду: речь идет об обучении, а не о пламени. - person aurora; 23.04.2010
comment
Я согласен с тем, что написал Норман (вот почему он получил бы мой голос, если бы у меня была репутация!). Я не могу добавить ничего, кроме личной эстетики его использования - мне просто так лучше. Опять же, YMMV :) FWIW, когда я перескакиваю между разными стилями сопоставления регулярных выражений / шаблонов (например, sed против Lua), это вызывает у меня головную боль и часто вызывает документацию. Я стараюсь оставаться в инструменте, который я использую чаще всего для этого, которым является Lua. - person Keith Pimmel; 23.04.2010

Хорошо, небольшая заметка для этого обсуждения; Меня особенно смутила эта страница:

Регулярные выражения SciTE

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

$ lua
Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> c="   d"
> print(c:match(" "))

> print(c:match("."))

> print(c:match("\s"))
nil
> print("_".. c:match("[ ]") .."_")
_ _
> print("_".. c:match("[ ]*") .."_")
_   _
> print("_".. c:match("[\s]*") .."_")
__

Хммм ... кажется, \s здесь не распознается - так что эта страница, вероятно, относится к регулярному выражению в Scite Find / Replace, а не к синтаксису регулярных выражений Lua (который scite также использует).

Затем я перечитываю lua-users wiki: Patterns Tutorial и начинаю получать комментарии о escape-символе является %, а не \ в ответе @NormanRamsey. Итак, пробуя это:

> print("_".. c:match("[%s]*") .."_")
_   _

... действительно работает.

Итак, поскольку я изначально думал, что "шаблоны" Lua - это разные команды / движок Lua "регулярное выражение", я думаю, лучший способ сказать это: "шаблоны" Lua специфичны для Lua " регулярное выражение "синтаксис / движок (другими словами, их не два :))

Ваше здоровье!

person sdaau    schedule 02.05.2012

Рискуя получить несколько отрицательных голосов за то, что говорю правду, я буду откровенен об этом (как, в конце концов, ответ должен быть): помимо возможности вернуть несколько захватов для одного вызова совпадения (возможно в регулярных выражениях, но гораздо более запутанным образом) и шаблон %bxy, который соответствует сбалансированной паре разделителей (например, все виды скобок и т. д.) и квалифицируется как полезный, мощный и лучший , почти все, что могут делать шаблоны Lua, также могут выполнять регулярные выражения.

С другой стороны, недостатки шаблонов Lua по сравнению с регулярными выражениями, когда дело доходит до функций, значительны, и их слишком много упоминается (например, отсутствие OR, отсутствие групп, не связанных с захватом, выражений просмотра и т. Д.). Теперь это было бы сбалансировано, если бы, скажем, шаблоны Lua были бы значительно быстрее, чем обычно более медленные регулярные выражения, но я не уверен, существует ли - и где - такое сравнение, которое исключало бы общую скорость Lua из-за его легкий характер, использование столов и так далее.

Настоящая причина, по которой Lua не потрудился добавить регулярные выражения в свой набор инструментов, не может заключаться в длине необходимого кода (это ерунда, современные компьютеры даже не мигают, когда речь идет о 4000 строках кода против всего 500, даже если он немного иначе переводится в библиотеку), но, вероятно, это связано с тем, что, будучи языком сценариев, предполагалось, что родительский язык уже включает возможность использования регулярных выражений. При взгляде на общую картину становится очевидным, что Lua как язык был разработан с учетом простоты, скорости и только необходимых функций. В большинстве случаев он работает хорошо, но если вам нужно больше возможностей в этой области, и вы не можете воспроизвести их с помощью других функций Lua, регулярные выражения являются более всеобъемлющими.

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

person Yin Cognyto    schedule 26.05.2021