2008-12-09 2 views
2

Я пытаюсь сделать некоторые простые форматирования с помощью «sed» в linux, и мне нужно использовать регулярное выражение для обрезки строки после 15-го символа и добавления «...» до конца. Что-то вроде этого:Regex: заменить все символы после 15-го на «...»

before: this is a long string that needs to be shortened 
after: this is a long ... 

Может кто-нибудь пожалуйста, покажите мне, как я мог бы написать это как регулярное выражение, и, если это возможно объяснить, как это работает, так что я мог бы научиться Regex немного лучше?

ответ

17

следующие работы для меня:

echo "This is a test with more than 15 characters" | sed "s/\(.\{15\}\).\+$/\1…/" 

Что здесь происходит, что мы любой символ (.) 15 раз ({15}). Мы фиксируем текст, согласованный в круглых скобках. Следующая часть (.+$) соответствует всем остальным, до конца строки. Мы заменяем это тем, что мы зафиксировали в круглых скобках (\1), за которым следует гиперболический многоточие.

Чтобы удовлетворить диалекту регулярного выражения sed (BRE), нам нужно избежать некоторых символов.

+2

Возможно, должно быть это. + Вместо. *, Так что оно не соответствует строке ровно 15 символов. – 2008-12-09 21:45:07

1

С Perl регулярных выражений:

$ echo 'this is a long string that needs to be shortened' \ 
| perl -pe 's/^(.{15}).+/$1.../' 
this is a long ... 

Самый простой способ думать о регулярных выражений, чтобы считать это модель, которая должна быть согласована. В этом случае шаблон начинается с начала строки:

^ 

(Обратите внимание, что / произвольный разделитель Другие символы могут быть использованы вместо этого.). В ^ является символом, который представляет собой начало строки в регулярное выражение. Далее регулярное выражение соответствует любому символу:

^. 

. является регулярным выражением символа для любого символа. Но мы хотим соответствовать первым 15 символам:

^.{15} 

Существует несколько различных модификаторов, которые представляют собой повторение. Наиболее распространенным является *, что означает 0 или более. A + указывает 1 или больше. {15}, очевидно, представляет ровно 15. (The {...} нотации является более общим Так * может быть написано {0,} и + такими же, как {1,}.). Теперь нам нужно захватить первые 15 символов, так что мы можем использовать их позже:

^(.{15}) 

Все между ( и ) захватывается и помещается в специальную переменную под названием $1 (или иногда \1). Второй захваченный фрагмент будет помещен в $2 и так далее.И, наконец, вы должны соответствовать до конца строки, так что вы можете бросить эту часть прочь:

^(.{15}).+ 

Первоначально я использовал *, но, как другой человек указал, что, вероятно, не то, что хотел, когда строка ровно 15 символов:

$ echo 'this is a long ' \ 
| perl -pe 's/^(.{15}).*/$1.../' 
this is a long ... 

Используя + означает образец не будет соответствовать, если не 16-й символ для замены.

Вторая половина утверждения, что печатается:

$1... 

$1 переменная, которую мы поймали раньше, используется и точки являются дословным . s на этой стороне замещения. Как правило, все, кроме переменных регулярного выражения, является буквальным в правой части оператора замещения.

+0

Очень хороший ответ, спасибо. – EgoPingvina 2016-12-22 11:33:50

0

В perl, вы можете написать s/(.{15}).*/$1.../. Я не уверен, что sed может использовать нотацию {15}, но если нет, s/\(...............\).*/\1.../ (с 15 точками в группе).

Я никогда не помню, нужно ли вам избегать ( при группировке в sed. Я просто попытался это и вам нужно \( и \)

6

Объяснение ответа Konrand Рудольфа, так как вы просили объяснений (ах, как я писал это, Konrad тоже добавил свое собственное объяснение!)

sed "s/\(.\{15\}\).+$/\1…/" 

\( 

Запустите группа - задать регулярное выражение двигатель, чтобы помнить, что находится внутри скобок, и назначить первую такую ​​группу \ 1, второе \ 2 и т.д. Нам понадобится только \ 1 здесь

. 

матч ничего ...

\{15\} 

... 15 раз.

\) 

конец группы. Таким образом, \ 1 будет содержать первые 15 символов

.+ 

соответствует чему-либо еще. + Означает «один или более раз», так будет соответствовать символы, выходящие за рамки 15 символов мы совпавших выше, ...

$ 

... до конца строки

Теперь для замены бита :

\1 

Заменить содержимое \ 1

... 

и тремя точками.

Выполнено!

+0

Typo: вы пишете \}, когда имеете в виду \\), чтобы завершить группу. – strager 2008-12-09 21:50:48

0

Вы действительно хотите просто ударить все после 15-го символа, или вы пытаетесь наложить максимальную длину 15 символов? Что, если строка длиной 16 символов? Все представленные решения до сих пор отрубают этот один лишний символ только для его замены тремя точками. (Я знаю, что Конрад и Пол использовали символ эллипсиса, но OP использовал три точки в этом примере, мы должны принять это решение.)

Если вы хотите обрезать строки до максимальной длины 15 , включая три точки, вы можете сделать это:

s/^\(.\{12\}\).\{3\}.\+$/\1.../ 

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

Смежные вопросы