Tome esta expressão regular: /^[^abc]/
. Isso corresponderá a qualquer caractere único no início de uma sequência, exceto a, b ou c.
Se você adicionar um *
depois dele - /^[^abc]*/
- a expressão regular continuará adicionando cada caractere subseqüente ao resultado, até encontrar um a
, ou b
, ou c
.
Por exemplo, com a cadeia de origem "qwerty qwerty whatever abc hello"
, a expressão corresponderá a "qwerty qwerty wh"
.
Mas e se eu quisesse que a string correspondente fosse "qwerty qwerty whatever "
... Em outras palavras, como posso combinar tudo até (mas não incluindo) a sequência exata "abc"
?
match but not including
?"qwerty qwerty whatever "
- sem incluir o "abc". Em outras palavras, não quero que a correspondência resultante seja"qwerty qwerty whatever abc"
.do string.split('abc')[0]
. Certamente não é uma resposta oficial para esse problema, mas acho mais direto que o regex.Respostas:
Você não especificou qual sabor de regex está usando, mas isso funcionará em qualquer um dos mais populares que podem ser considerados "completos".
Como funciona
A
.+?
parte é a versão não gulosa de.+
(uma ou mais de qualquer coisa). Quando usamos.+
, o mecanismo basicamente corresponde a tudo. Então, se houver algo mais no regex, ele voltará em etapas tentando corresponder à parte a seguir. Esse é o comportamento ganancioso , que significa o máximo possível de satisfação .Ao usar
.+?
, em vez de corresponder tudo de uma vez e voltar para outras condições (se houver), o mecanismo corresponderá aos próximos caracteres passo a passo até que a parte subsequente da regex seja correspondida (novamente, se houver). Este é o não-ganancioso , ou seja, corresponder ao mínimo possível de satisfação .Depois disso, temos uma asserção de largura zero , uma olhada em volta . Essa construção agrupada corresponde ao seu conteúdo, mas não conta como caracteres correspondentes ( largura zero ). Ele retorna apenas se for uma correspondência ou não ( asserção ).
(?=
{contents}
)
Assim, em outros termos, o regex
/.+?(?=abc)/
significa:fonte
.+?
e.*
?+
significa 1 ou mais, onde*
significa 0 ou mais. A inclusão / exclusão do?
irá torná-lo ganancioso ou não ganancioso.^(?:(?!abc)(?!def).)*
pode encadear para excluir padrões que não deseja e ainda assim agarra tudo conforme necessário, mesmo que o padrão não existaSe você deseja capturar tudo até "abc":
Explicação:
( )
capturar a expressão dentro dos parênteses para o acesso usando$1
,$2
etc.^
coincidir com o início da linha.*
corresponde a qualquer coisa,?
sem avidez (corresponde ao número mínimo de caracteres necessário) - [1][1] A razão pela qual isso é necessário é que, caso contrário, na seguinte string:
por padrão, as expressões regulares são gananciosas , o que significa que corresponderá o máximo possível. Portanto
/^.*abc/
corresponderia "qualquer coisa que seja algo abc algo". A adição do quantificador não-ganancioso?
faz com que o regex corresponda apenas "a qualquer coisa que seja".fonte
sed
parece não suportar correspondência não gananciosa, nem look-around ((?=...)
). O que mais eu posso fazer? Comando Exemplo:echo "ONE: two,three, FOUR FIVE, six,seven" | sed -n -r "s/^ONE: (.+?), .*/\1/p"
retornostwo,three, FOUR FIVE
, mas esperotwo,three
...two
, nãotwo,three
.Como @Jared Ng e @Issun apontaram, a chave para resolver esse tipo de RegEx como "corresponder tudo a uma determinada palavra ou substring" ou "corresponder tudo após uma determinada palavra ou substring" é chamada de asserções de comprimento zero "lookaround" . Leia mais sobre eles aqui.
No seu caso particular, isso pode ser resolvido com um olhar positivo à frente:
.+?(?=abc)
Uma imagem vale mais que mil palavras. Veja a explicação detalhada na captura de tela.
fonte
.+?(?=abc)
regex de copiar e colar vale mais.O que você precisa é olhar em volta da afirmação
.+? (?=abc)
.Veja: Lookahead e Lookbehind Zero-Length Assertions
Esteja ciente de que
[abc]
não é o mesmo queabc
. Entre parênteses, não é uma string - cada caractere é apenas uma das possibilidades. Fora dos colchetes, ele se torna a corda.fonte
Para regex em Java, e acredito também na maioria dos mecanismos de regex, se você quiser incluir a última parte, isso funcionará:
Por exemplo, nesta linha:
selecione todos os caracteres até "abc" e também inclua abc
usando nossa regex, o resultado será:
I have this very nice senabc
Teste isso: https://regex101.com/r/mX51ru/1
fonte
Eu terminei nesta questão de stackoverflow depois de procurar ajuda para resolver o meu problema, mas não encontrei uma solução para ele :(
Então eu tive que improvisar ... depois de algum tempo, consegui alcançar o regex que eu precisava:
Como você pode ver, eu precisava de até uma pasta antes da pasta "grp-bps", sem incluir o último traço. E era necessário ter pelo menos uma pasta após a pasta "grp-bps".
Editar
Versão em texto para copiar e colar (altere 'grp-bps' no seu texto):
fonte
Isso fará sentido sobre regex.
Aqui, podemos obter a palavra exata globalmente que pertence às aspas duplas. Por exemplo, se nosso texto de pesquisa for,
Este é o exemplo das palavras "aspas duplas"
então seremos "citados duas vezes" nessa frase.
fonte
"
que, para mim, parece irrelevante para a questão.No python:
.+?(?=abc)
funciona para o caso de linha única.[^]+?(?=abc)
não funciona, já que o python não reconhece [^] como regex válido. Para fazer a correspondência multilinha funcionar, você precisará usar a opção re.DOTALL, por exemplo:fonte
Eu acredito que você precisa de subexpressões. Se bem me lembro, você pode usar os
()
colchetes normais para subexpressões.Esta parte é do manual grep:
Faça algo como
^[^(abc)]
deve fazer o truque.fonte
Como
$
marca o final de uma string, algo assim deve funcionar:[[^abc]*]$
onde você está procurando por algo que NÃO TERMINA em qualquer iteraçãoabc
, mas teria que estar no finalAlém disso, se você estiver usando uma linguagem de script com regex (como php ou js), eles têm uma função de pesquisa que para quando encontra um padrão pela primeira vez (e você pode especificar iniciar da esquerda ou da direita ou com php, você pode implodir para espelhar a string).
fonte
tente isso
Inquerir :
resultado :
fonte