Regex: correspondendo até a primeira ocorrência de um caractere


358

Estou procurando um padrão que corresponda a tudo até a primeira ocorrência de um caractere específico, digamos ";" - um ponto e vírgula .

Eu escrevi isto:

/^(.*);/

Mas na verdade corresponde a tudo (incluindo o ponto e vírgula) até a última ocorrência de um ponto e vírgula.


65
/^(.*?);/também deve funcionar (é chamado de não ganancioso ), mas as respostas fornecidas [^;]*são melhores.
— Pascal

como você selecionaria tudo, após ponto e vírgula, e não o ponto e vírgula em si.
— Muhammad Umer

veja isso funciona, \w+(?!([^]+;)|;)mas isso não acontece por quê? .+(?!([^]+;)|;)
— Muhammad Umer

11
Pascal, você deveria ter escrito isso como resposta!
— Sean Kendle

@ Pascal Isso é adequado como resposta! Obrigado!
— NeverMind9 /

Respostas:


503

Você precisa

/[^;]*/

A classe[^;] é de personagem , corresponde a tudo, exceto um ponto e vírgula.

Para citar a página de perlremanual:

Você pode especificar uma classe de caracteres anexando uma lista de caracteres em [], que corresponderá a qualquer caractere da lista. Se o primeiro caractere após o "[" for "^", a classe corresponderá a qualquer caractere que não esteja na lista.

Isso deve funcionar na maioria dos dialetos regex.


A grande parte dessa solução é que também corresponde ao final da linha, por exemplo, no meu caso, foo=bar;baz=bax;bab=bafe ela corresponde bab=bafmesmo que não haja ;exatamente o que eu preciso. Não sei por que ele funciona embora se especificação diz partidas tudo, mas o símbolo do alvo ...
— skryvets


38

/^[^;]*/

O [^;] diz corresponde a qualquer coisa, exceto um ponto e vírgula. Os colchetes são um operador de correspondência de conjunto, essencialmente, corresponde a qualquer caractere nesse conjunto de caracteres; ^no início, ele é uma correspondência inversa, portanto, corresponda a qualquer coisa que não esteja nesse conjunto.


3
Esteja ciente de que o primeiro ^ nesta resposta concede ao regex um significado completamente diferente: Faz com que a expressão regular procure apenas correspondências começando no início da string. Nesse caso, isso seria eficaz se você executasse a expressão regular apenas uma vez. Se você deseja procurar várias correspondências dentro de uma única string, o primeiro ^ precisaria desaparecer.
— Dan Breslau

4
Ele disse que queria combinar tudo até a primeira ocorrência de ponto-e-vírgula, então presumi que ele quis dizer isso desde o início da string.
— Glenn Slaven



8

texto de amostra:

"this is a test sentence; to prove this regex; that is g;iven below"

Se, por exemplo, tivermos o texto de exemplo acima, o regex /(.*?\;)/fornecerá tudo até a primeira ocorrência de ponto e vírgula ( ;), incluindo o ponto e vírgula:"this is a test sentence;"


3
não é necessário escapar do ;char, pois não é um caráter especial de regex. O agrupamento ()também não é necessário. Você pode ir com/.*?;/
— Aliaksei Kliuchnikau

11
Sim, você está certo. a escapar era mais como "melhor prevenir do que remediar"
— poncius

2
Esta é a resposta que eu estava procurando. Então o ? faz a partida terminar na primeira ocorrência? Qual é o nome dessa propriedade ... (vamos chamá-la) da regex?
— Parziphal

11
@Parziphal o ?personagem torna a partida preguiçosa (combinando o menor número de vezes possível). Pense nos personagens regex correspondência até o primeiro ponto e vírgula, então não ir mais longe, porque dá-se (preguiçoso;))
— derekantrican

5

essa não é uma solução de regex, mas algo bastante simples para a descrição do seu problema. Basta dividir sua string e obter o primeiro item da sua matriz.

$str = "match everything until first ; blah ; blah end ";
$s = explode(";",$str,2);
print $s[0];

resultado

$ php test.php
match everything until first

5

Isso foi muito útil para mim, pois estava tentando descobrir como combinar todos os caracteres em uma tag xml, incluindo atributos. Eu estava correndo para o problema "combina tudo até o fim" com:

/<simpleChoice.*>/

mas conseguiu resolver o problema com:

/<simpleChoice[^>]*>/

depois de ler este post. Obrigado a todos.


11
Eu descobri que é muito mais eficiente analisar (cada linguagem ou estrutura possui suas próprias classes para isso) html / xml por causa de seu formato de máquina, as expressões regulares são para linguagem natural.
— Leon Fedotov

11
Agradável. Eu usei isso para corrigir documentos xml com erros de sintaxe na <!DOCTYPE>tag. Desde analisador não foi capaz de lidar com isso.
— Martin Schneider

5

Isso corresponderá à primeira ocorrência apenas em cada sequência e ignorará as ocorrências subsequentes.

/^([^;]*);*/

3

"/^([^\/]*)\/$/" funcionou para mim, para obter apenas as "pastas" principais de uma matriz como:

a/   <- this
a/b/
c/   <- this
c/d/
/d/e/
f/   <- this

2

Realmente meio triste que ninguém tenha lhe dado a resposta correta ....

Em regex,? torna não ganancioso. Por padrão, o regex corresponderá o máximo possível (ganancioso)

Basta adicionar um? e não será ganancioso e corresponderá o mínimo possível!

Boa sorte, espero que ajude.


3
Isso depende muito da implementação real do regex e nem toda implementação possui um modo não ganancioso.
— 22815

0

eu achei aquilo

/^[^,]*,/

funciona bem.

',' sendo o "delimitador" aqui.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.