Expressão regular para parar na primeira partida


531

Meu padrão regex se parece com

<xxxx location="file path/level1/level2" xxxx some="xxx">

Estou interessado apenas na parte entre aspas atribuídas ao local. Não deveria ser tão fácil como abaixo sem a opção gananciosa?

/.*location="(.*)".*/

Não parece funcionar.


Qual é a sua fonte, é HTML ou xml ou algo assim?
Oskar Kjellin

20
Por que este é um wiki da comunidade? É uma pergunta real. Tarde demais agora.
Ahmad Mageed 23/03/10

1
Em que idioma você está escrevendo? Por favor, não use regex para XML. Existem tantas maneiras melhores de analisar XML
Oskar Kjellin 23/03

3
Não, se tudo o que você deseja é procurar atributos simples. Regex é apropriado e mais rápido.
Codenheim

Eu diria que, se você por exemplo codificar c #, é muito melhor usar o linq para isso. Eu duvido que ele vai ser melhor para regex se você tiver um bom analisador
Oskar Kjellin

Respostas:


1096

Você precisa tornar sua expressão regular não ambiciosa, porque, por padrão, "(.*)"corresponderá a todos "file path/level1/level2" xxx some="xxx".

Em vez disso, você pode tornar sua estrela de ponto não gananciosa, o que fará com que ele corresponda ao mínimo de caracteres possível:

/location="(.*?)"/

Adicionando a ?em um quantificador (? , *ou +) torna-o não ganancioso.


32
FWIW, caso você use o VIM, esse regex precisa ser um pouco diferente: em vez de .*?ser .\{-}para uma correspondência não gananciosa.
SooDesuNe 24/03

44
Obrigado Daniel. "Adicionar um? Em um quantificador (?, * Ou +) torna-o não ganancioso." é uma dica útil para mim.
PhatHV

10
O ? descreve minha confusão ao tentar descobrir isso. Quão apropriado.
22616 Robbie Smith

1
Eu acredito que você pode dizer 'preguiçoso' em vez de 'não-ganancioso'
Manticore

50

location="(.*)"corresponderá do "depois location=até o" depois, a some="xxxmenos que você o torne não ganancioso. Então você precisa .*?(ou seja, não seja ganancioso) ou melhor substitui-o .*por [^"]*.


3
[^ "] * Também é provavelmente mais rápido com a maioria dos motores regex porque ele não precisa procurar o padrão após o padrão atual.
Jean Vincent

1
@Kip: Você provavelmente está certo, mas a .*?notação é mais geral do que[^"]*
Bondax

como sobre se eu quiser incluir o caractere delimitador usando [^ "] *
Frohlich

de maneira alguma, se você não sabe o que ^ e [] significam aqui. A maioria das pessoas entenderá. *
Vincent Gerris

31

E se

.*location="([^"]*)".*

Isso evita a pesquisa ilimitada com. * E corresponderá exatamente à primeira cotação.


Devido a discrepâncias no grep, o padrão acima deve ser o preferido se a portabilidade for uma preocupação.
Josh Habdas

22

Use correspondência não gananciosa, se o seu mecanismo suportar. Adicione o ? dentro da captura.

/location="(.*?)"/

11

O uso de quantificadores preguiçosos ?sem bandeira global é a resposta.

Por exemplo,

insira a descrição da imagem aqui

Se você tivesse uma bandeira global /g, ela corresponderia a todas as correspondências de menor comprimento, conforme abaixo. insira a descrição da imagem aqui


1

Como você está usando sub - padrão quantificado e conforme descrito no Perl Doc ,

Por padrão, um sub-padrão quantificado é " ganancioso ", ou seja, corresponderá o maior número de vezes possível (dado um local de partida específico), enquanto ainda permite que o restante do padrão seja correspondido. Se você deseja que ele corresponda ao número mínimo de vezes possível, siga o quantificador com um "?" . Note que os significados não mudam, apenas a "ganância":

*?        //Match 0 or more times, not greedily (minimum matches)
+?        //Match 1 or more times, not greedily

Portanto, para permitir que seu padrão quantificado faça a correspondência mínima, siga-o ?:

/location="(.*?)"/

1

Aqui está outra maneira.

Aqui está o que você deseja. Isso é preguiçoso[\s\S]*?

O primeiro item: [\s\S]*?(?:location="[^"]*")[\s\S]* Substitua por:$1

Explicação : https://regex101.com/r/ZcqcUm/2


Para ser completo, esse é o último. Isso é ganancioso[\s\S]*

O último item:[\s\S]*(?:location="([^"]*)")[\s\S]* Substitua por:$1

Explicação : https://regex101.com/r/LXSPDp/3


Há apenas uma diferença entre essas duas expressões regulares e esse é o ?

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.