Regex: substituir todos os caracteres após 15 com '...'

votos
2

Eu estou tentando fazer algumas coisas formatação simples com 'sed' no linux, e eu preciso usar um regex para cortar uma corda após o caractere 15, e anexar um '...' até o fim. Algo assim:

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

Alguém por favor pode me mostrar como eu poderia escrever isso como um regex e, se possível explicar como funciona para que eu pudesse aprender regex um pouco melhor?

Publicado 09/12/2008 em 22:35
fonte usuário
Em outras línguas...                            


5 respostas

votos
17

Os seguintes trabalhos para mim:

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

O que acontece aqui é que nós corresponder a qualquer caractere ( .) 15 vezes ( {15}). Nós capturar o texto de modo combinado entre parênteses. A parte seguinte ( .+$) corresponde a todo o resto, até que o fim da linha. Nós substituir este por qualquer coisa que tenha capturado dentro dos parênteses ( \1), seguido pelo reticências hiperbólica.

Para satisfazer seddialeto regex 's (BRE), temos de escapar alguns dos personagens.

Respondeu 09/12/2008 em 22:38
fonte usuário

votos
6

Explicação da resposta de Konrand Rudolph, desde que você solicitou explicações (ah, como eu escrevi isso, Konrad acrescentou sua própria explicação também!)

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

\( 

iniciar um grupo - pergunte o motor regexp para lembrar o que está dentro dos parênteses, e atribuir o primeiro tal grupo de \ 1, o segundo para \ 2 etc. Nós só precisará \ 1 aqui

.

Combinar qualquer coisa ...

\{15\}

... 15 vezes.

\)

terminar o grupo. Então \ 1 conterá os primeiros 15 caracteres

 .+

corresponde a nada de novo. O + significa "uma ou mais vezes", então irá corresponder caracteres para além dos 15 personagens que combinaram acima, ...

 $

... até o fim da linha

Agora, para o bit substituir:

\1

Substituir com o conteúdo de \ 1

...

e três pontos.

Feito!

Respondeu 09/12/2008 em 22:46
fonte usuário

votos
1

Com expressões regulares Perl:

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

A maneira mais fácil de pensar em expressões regulares é considerá-lo um padrão que precisa ser correspondida. Neste caso, o padrão começa com o início da linha:

^

(Note-se que /é um separador arbitrária. Outros caracteres poderia ser utilizado em vez disso). A ^é o símbolo que representa o início da linha de expressão regular. Em seguida, o regex corresponde a qualquer caractere:

^.

Um .é o símbolo regex para qualquer personagem. Mas queremos corresponder os primeiros 15 caracteres:

^.{15}

Existem vários modificadores diferentes que representam uma repetição. O mais comum é *que significa 0 ou mais. Um +indica um ou mais. {15}obviamente, representa exatamente 15. (As {...}notações é mais geral Então. *poderia ser escrito {0,}e +é o mesmo que {1,}.) Agora precisamos captar os primeiros 15 caracteres para que possamos usá-los mais tarde:

^(.{15})

Tudo entre (e )é capturado e colocado em uma variável especial chamada $1(ou às vezes \1). O segundo pedaço capturado seria colocado no $2e assim por diante. Finalmente, você precisa combinar com o fim da linha para que você pode jogar essa parte afastado:

^(.{15}).+

Eu inicialmente utilizado *, mas como outra pessoa apontou, que provavelmente não é o que se deseja quando a corda é exatamente 15 caracteres:

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

Usando um +meio o padrão não irá corresponder se não houver um 16 th personagem para substituir.

A segunda metade da declaração é o que será impresso:

$1...

A $1variável que nos encontramos no início é usado e os pontos são literais .s deste lado da substituição. Geralmente, tudo, exceto variáveis regex são literal no lado direito de uma instrução de substituição.

Respondeu 09/12/2008 em 22:39
fonte usuário

votos
0

Você realmente quer apenas bater fora de tudo após o caractere 15, ou você está tentando impor um comprimento máximo de 15 caracteres? O que se a cadeia é de 16 caracteres? Todas as soluções apresentadas até agora vai cortar que apenas um caráter excesso de substituí-lo por três pontos. (Eu sei Konrad e Paulo usou o personagem de reticências, mas o OP usado três pontos no exemplo;. Devemos ter uma decisão sobre isso)

Se você deseja cortar as cordas para um comprimento máximo de 15 , incluindo os três pontos , você pode fazer isso:

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

Ainda corresponde apenas se houver mais de 15 caracteres, mas então ele corta tudo após o caráter 12 para dar espaço para os pontos.

Respondeu 10/12/2008 em 05:06
fonte usuário

votos
0

Em perl, você pode escrever s/(.{15}).*/$1.../. Eu não tenho certeza sed pode usar o {15} notação mas se não, s/\(...............\).*/\1.../(com 15 pontos no grupo).

Eu nunca me lembro se você precisa escapar (ao agrupar em sed. Eu apenas tentei isso e você precisa \(e\)

Respondeu 09/12/2008 em 22:42
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more