#grammar #raku
#грамматика #raku
Вопрос:
Я пытаюсь избежать сопоставления пробелов в конце строки, при этом все еще сопоставляя пробелы в середине слов.
Вот пример регулярного выражения, которое соответствует символам подчеркивания внутри x
, но не соответствует трем завершающим символам подчеркивания.
say 'x_x___x________' ~~ / [ | 'x' | '_' <!before [ | $ | '_' <?before
gt;
| '_' <?before ['_' <?beforegt;]>
| '_' <?before ['_' <?before ['_' <?beforegt;]>]>
# ...
]>
]
/;
Есть ли способ построить остальную часть шаблона, подразумеваемого...
?
Комментарии:
1. Вероятно, самый простой способ избежать сопоставления пробелов в конце строки, но сопоставлять их где-либо еще — это делать это совсем по-другому::
s <!before $>
Это соответствует всем разделам пробелов, если оно не находится прямо перед концом строки
Ответ №1:
Немного сложно понять, о чем вы просите.
Возможно, вы ищете что-то такое простое, как это:
say 'x_x___x________' ~~ / 'x' % '_' ** 1..3 /
# 「x_x___x」
или
say 'x_x___x________' ~~ / 'x' % '_' ** 1..2 /
# 「x_x」
или
say 'x_x___x________' ~~ / 'x' % '_' /
# 「x_x___x」
Комментарии:
1. Я вижу, что @brad (?) ответил на ваш актуальный вопрос — вот ссылка на модифицированный квантификатор для разделителей в документе [ docs.raku.org/language/regexes#Modified_quantifier :_%,_%%]
2. По сути, это решение, на котором я остановился :
/ ['x' ] % '_' /
. Однако я думаю, что в конечном итоге я ищу способ сопоставления произвольно длинных потоков, которые заканчиваются известным шаблоном. Я попытаюсь немного прояснить вопрос.
Ответ №2:
Я бы предложил использовать захват …, таким образом:
'x_x___x________' ~~ /(.*?) _* $/;
say $0; #「x_x___x」
(Что? модификатор делает * ‘нежадным’.)
Пожалуйста, дайте мне знать, если я пропустил главное!
Комментарии:
1. или, более компактно,
say ('x_x___x________' ~~ /(.*?) _* $/)[0];
Ответ №3:
избегайте сопоставления пробелов в конце строки, сохраняя при этом соответствие пробелов в середине слов
Согласно ответу Брэда и вашему комментарию к нему, что-то вроде этого:
/ w % s /
то, что я ищу, — это способ сопоставления произвольно длинных потоков, которые заканчиваются известным шаблоном
Согласно комментарию @user0721090601 к вашему вопросу и в качестве варианта ответа @p6steve, что-то вроде этого:
/ w % s )> s* $ /
<a rel=»noreferrer noopener nofollow» href=»https://docs.raku.org/language/regexes#index-entry-regex_-Capture_markers:_» rel=»nofollow noreferrer»>Маркер )>
захвата отмечает, где захват должен заканчиваться.
Вы можете использовать произвольные шаблоны слева и справа от этого маркера.
бесконечное семейство
<!before>
шаблонов
Обобщая на бесконечное семейство шаблонов любого типа, независимо от того, имеют они нулевую ширину или нет, наиболее естественным решением в регулярном выражении является итерация с использованием любого из стандартных кванторов с открытым концом. Например, s
для одного или нескольких пробелов.[1] [2]
Есть ли способ построить остальную часть шаблона, подразумеваемого
...
?
Я обобщу это так: «Есть ли в регулярном выражении Raku способ сопоставить некоторый произвольный шаблон, который теоретически может быть распознан компьютерной программой?»
Ответ всегда «Да»:
- Хотя правила / регулярные выражения Raku могут выглядеть как традиционные регулярные выражения, на самом деле они являются произвольными функциями, встроенными в произвольную программу, над которой вы в конечном итоге имеете полный контроль.
- Правила имеют произвольный доступ для чтения к состоянию захвата.[3]
- Правила могут выполнять произвольное полное вычисление по Тьюрингу.[4]
- Набор правил / регулярных выражений может произвольно использовать входные данные и управлять состоянием синтаксического анализа / сопоставления, т. Е. Может реализовать любой синтаксический анализатор.
Короче говоря, если он может быть сопоставлен / проанализирован любой программой, написанной на любом языке программирования, он может быть сопоставлен / проанализирован с использованием правил / регулярных выражений Raku.
Сноски
[1] Если вы используете квантификатор с открытым концом, вам нужно убедиться, что каждая итерация / рекурсия сопоставления либо использует хотя бы один символ, либо завершается ошибкой, чтобы избежать бесконечного цикла. Например, *
квантификатор будет успешным, даже если шаблон, который он определяет, не соответствует, поэтому будьте осторожны, чтобы это не привело к бесконечному циклу.
[2] Учитывая то, как вы написали свой пример, возможно, вам интересна рекурсия, а не итерация. Достаточно сказать, что это тоже легко сделать.[1]
[3] В правилах Raku захваты образуют иерархию. Есть две специальные переменные, которые отслеживают состояние захвата двух ключевых уровней этой иерархии:
$¢
является состоянием захвата самого внутреннего охватывающего общего захвата. Думайте об этом как о чем-то аналогичном возвращаемому значению, создаваемому текущим вызовом функции в стеке вызовов функций.$/
является состоянием захвата самого внутреннего охватывающего захвата. Думайте об этом как о чем-то аналогичном значению, создаваемому определенным блоком кода внутри функции.
Например:
'123' ~~ / 1* ( 2* { print "$¢ $/" } ) 3* { print "$¢ $/" } / ; # 1 2123 123
- В целом
/ ... /
аналогично обычному вызову функции. Первый1
и первый123
из выходных данных показывают, что было захвачено этим общим регулярным выражением. ( ... )
Настраивает внутренний захват для части регулярного выражения.2* { print "$¢ $/" }
Внутри него аналогично блоку кода.2
Показывает, что он захватил.- Финал
123
показывает, что на верхнем уровне регулярного$/
выражения и$¢
имеют одинаковое значение.
[4] Например, код в сноске 3 выше включает произвольный код внутри { ... }
блоков. В более общем плане:
- Правила могут вызываться рекурсивно;
- Правила могут иметь полные подписи и передавать аргументы;
- Правила могут содержать произвольный код;
- Правила могут использовать множественную семантику отправки для разрешения. Примечательно, что это может включать разрешение на основе наибольшей длины совпадения.
Ответ №4:
Мне интересно trim()
, могут ли процедуры Raku соответствовать вашим целям, например: .trim
, .trim-trailing
или даже .trim-leading
. В Raku REPL:
> say 'x x x ' ~~ m:g/ 'x' s* /;
(「x 」 「x 」 「x 」)
> say 'x x x '.trim-trailing ~~ m:g/ 'x' s* /;
(「x 」 「x 」 「x」)
HTH.
https://docs.raku.org/routine/trim https://docs.raku.org/routine/trim-trailing https://docs.raku.org/routine/trim-leading