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.