Реализация регулярного выражения для замены группы на строчную версию - PullRequest
48 голосов
/ 09 января 2009

Существует ли реализация регулярного выражения, позволяющая заменить группу в регулярном выражении ее строчной версией?

Ответы [ 6 ]

58 голосов
/ 15 мая 2009

Если ваша версия regex поддерживает это, вы можете использовать \ L, как в оболочке POSIX:

sed -r 's/(^.*)/\L\1/'
34 голосов
/ 09 января 2009

В Perl вы можете сделать:

$string =~ s/(some_regex)/lc($1)/ge;

Опция /e заставляет выражение замены интерпретироваться как код Perl, возвращаемое значение которого используется в качестве окончательного значения замены. lc($x) возвращает версию $x в нижнем регистре. (Не уверен, но я предполагаю, что lc() будет правильно обрабатывать международные символы в последних версиях Perl.)

/g означает совпадение во всем мире. Опустите g, если вам нужна только одна замена.

13 голосов
/ 23 января 2014

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

\L$1

в качестве замены, где $1 относится к чему-то из регулярного выражения, которое вы заключаете в скобки. Например, 2 , вот что я использовал, чтобы сократить имена полей в некотором SQL, получая все справа от «как» в конце любой данной строки. Сначала регулярное выражение "найти":

(as|AS) ([A-Za-z_]+)\s*,$

, а затем выражение для замены:

$1 '\L$2',

Если вы используете Vim (или, по-видимому, gvim), тогда вы захотите использовать \L\1 вместо \L$1, но есть еще одна проблема, о которой вам нужно знать: Vim изменяет синтаксис между буквенными скобками символы и экранированные символы в скобках. Поэтому для обозначения части регулярного выражения, которая будет включена в замену («захваченная»), вы будете использовать \( в начале и \) в конце. Думайте о \ как о - вместо экранирования специального символа, чтобы сделать его литералом - маркировка начала специального символа (как с \s, \w, \b и т. Д.). Так что это может показаться странным, если вы к этому не привыкли, но на самом деле совершенно логично, если вы думаете об этом в стиле Vim.


1 Я проверял это как в TextMate, так и в SublimeText, и он работает как есть, но некоторые редакторы используют \1 вместо $1. Попробуйте оба варианта и посмотрите, какой редактор использует.

2 Я только что вынул это регулярное выражение из своей истории. Я всегда настраиваю регулярное выражение при их использовании, и я не могу обещать, что это окончательная версия, поэтому я не предполагаю, что она подходит для описанной цели, и особенно, если SQL не отформатирован иначе, чем SQL, над которым я работал, просто конкретный пример сокращения в регулярных выражениях. YMMV. UAYOR.

6 голосов
/ 23 марта 2018

В нескольких ответах отмечено использование \L. Тем не менее, \E также стоит знать, если вы используете \L.

\L преобразует все до следующего \U или \E в нижний регистр. ... \E отключает преобразование регистра.

(Источник: https://www.regular -expressions.info / replacecase.html )

Итак, предположим, что вы хотите использовать rename для строчной части некоторых имен файлов, таких как:

artist_-_album_-_Song_Title_to_be_Lowercased_-_MultiCaseHash.m4a
artist_-_album_-_Another_Song_Title_to_be_Lowercased_-_MultiCaseHash.m4a

Вы могли бы сделать что-то вроде:

rename -v 's/^(.*_-_)(.*)(_-_.*.m4a)/$1\L$2\E$3/g' *
3 голосов
/ 09 января 2009

В Perl есть

$string =~ tr/[A-Z]/[a-z]/;
2 голосов
/ 09 января 2009

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

...