Я видел этот пример:
hello=ho02123ware38384you443d34o3434ingtod38384day
echo ${hello//[0-9]/}
Который следует этому синтаксису: ${variable//pattern/replacement}
К сожалению, pattern
поле не поддерживает полный синтаксис регулярных выражений (если я использую .
или \s
, например, оно пытается соответствовать буквенным символам).
Как я могу найти / заменить строку, используя полный синтаксис регулярных выражений?
\s
не является частью стандартного синтаксиса регулярных выражений, определенного POSIX (ни BRE, ни ERE); это расширение PCRE, и в основном недоступно из оболочки.[[:space:]]
является более универсальным эквивалентом.\s
может быть заменен[[:space:]]
, кстати, с.
помощью?
и extglob расширения языка шаблонов базовой оболочки может использоваться для таких вещей , как дополнительные подгруппы, повторяющихся групп, и тому подобное.Ответы:
Используйте sed :
Обратите внимание, что последующие
-e
обрабатываются по порядку. Кроме того,g
флаг для выражения будет соответствовать всем вхождениям на входе.Вы также можете выбрать свой любимый инструмент, используя этот метод, например, perl, awk, например:
Это может позволить вам делать больше творческих соответствий ... Например, в приведенном выше фрагменте замена чисел не будет использоваться, если в первом выражении не будет совпадения (из-за отложенной
and
оценки). И, конечно, у вас есть полная языковая поддержка Perl для выполнения ваших ставок ...источник
sed
или других внешних инструментов стоит дорого из-за времени инициализации процесса. Я особенно искал решение для всего bash, потому что я обнаружил, что использование замен bash более чем в 3 раза быстрее, чем вызовsed
каждого элемента в моем цикле.На самом деле это можно сделать в чистом виде:
... дает ...
источник
=~
это ключ. Но немного неуклюже, учитывая переназначение в цикле. Решение @jheddings за 2 года до этого - еще один хороший вариант - вызов sed или perl).sed
илиperl
имеет смысл, если использовать каждый вызов для обработки более чем одной строки ввода. Вызывать такой инструмент внутри цикла, в отличие от использования цикла для обработки его выходного потока, безрассудно.$match
вместо$BASH_REMATCH
. (Вы можете заставить его вести себя как ударsetopt bash_rematch
.)Эти примеры также работают в bash, нет необходимости использовать sed:
Вы также можете использовать скобочные выражения класса символов
вывод
Однако @Lanaru хотел знать, если я правильно понимаю вопрос, почему «полные» или расширения PCRE и
\s\S\w\W\d\D
т. Д. Не работают так, как это поддерживается в php ruby python и т. Д. Эти расширения взяты из Perl-совместимых регулярных выражений (PCRE) и может быть несовместимо с другими формами регулярных выражений на основе оболочки.Это не работает:
вывод с удалением всех буквенных символов "d"
но следующее работает как ожидалось
вывод
Надеюсь, это проясняет ситуацию немного больше, но если вы еще не запутались, почему бы не попробовать это на Mac OS X, у которой включен флаг REG_ENHANCED:
На большинстве разновидностей * nix вы увидите только следующий вывод:
NJoy!
источник
${foo//$bar/$baz}
это не POSIX.2 BRE или ERE синтаксис - это fnmatch () - сопоставление с шаблоном.${hello//[[:digit:]]/}
работает, если бы мы хотели отфильтровывать только цифры, перед которыми стоит букваo
,${hello//o[[:digit:]]*}
поведение было бы совершенно иным, чем ожидалось (так как в шаблонах fnmatch,*
совпадает со всеми символами, вместо изменения непосредственно предшествующего элемента, чтобы 0 или-больше).[0-9]
или[[:digit:]]
Если вы делаете повторные вызовы и обеспокоены производительностью, этот тест показывает, что метод BASH в ~ 15 раз быстрее, чем разветвление в sed и, вероятно, любой другой внешний процесс.
источник
Используйте
[[:digit:]]
(обратите внимание на двойные скобки) в качестве шаблона:Просто хотел обобщить ответы (особенно на @ nickl-'s https://stackoverflow.com/a/22261334/2916086 ).
источник
Я знаю, что это древняя ветка, но это был мой первый успех в Google, и я хотел бы поделиться следующим,
resub
что я собрал, добавив поддержку нескольких обратных ссылок $ 1, $ 2 и т. Д. ...H / T в @Charles Duffy re:
(.*)$match(.*)
источник