Como combinar “qualquer coisa até esta sequência de caracteres” em uma expressão regular?

Tome esta expressão regular: /^[^abc]/ . Isso corresponderá a qualquer caractere único no início de uma string, 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 string 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" ?

Você não especificou qual sabor de regex você está usando, mas isso funcionará em qualquer um dos mais populares que podem ser considerados “completos”.

 /.+?(?=abc)/ 

Como funciona

O. .+? parte é a versão não-gananciosa de .+ (um ou mais de qualquer coisa). Quando usamos .+ , O mecanismo basicamente combina com tudo. Então, se houver algo mais no regex, ele voltará em etapas tentando corresponder à parte a seguir. Esse é o comportamento ganancioso , o que significa , tanto quanto possível, satisfazer .

Ao usar .+? , em vez de corresponder de uma só vez e voltar para outras condições (se houver), o mecanismo corresponderá aos próximos caracteres a cada etapa até que a parte subsequente da regex seja correspondida (novamente, se houver). Este é o não-ganancioso , ou seja, corresponde ao menor número possível de satisfazer .

 /.+X/ ~ "abcXabcXabcX" /.+/ ~ "abcXabcXabcX" ^^^^^^^^^^^^ ^^^^^^^^^^^^ /.+?X/ ~ "abcXabcXabcX" /.+?/ ~ "abcXabcXabcX" ^^^^ ^ 

Depois disso temos (?= {contents} ) , uma afirmação de largura zero , uma olhada ao redor . Essa construção agrupada corresponde ao seu conteúdo, mas não conta como caracteres correspondentes ( largura zero ). Só retorna se for uma partida ou não ( afirmação ).

Assim, em outros termos, o regex /.+?(?=abc)/ significa:

Combine todos os caracteres o menos possível até que um “abc” seja encontrado, sem contar o “abc”.

Se você estiver procurando capturar tudo para “abc”:

 /^(.*?)abc/ 

Explicação:

( ) captura a expressão dentro dos parênteses para access usando $1 , $2 , etc.

^ partida do fósforo da linha

.* corresponde a alguma coisa ? não avidamente (corresponde ao número mínimo de caracteres requeridos) – [1]

[1] A razão pela qual isso é necessário é que, do contrário, na seguinte cadeia:

 whatever whatever something abc something abc 

Por padrão, as regexes são gananciosas , o que significa que elas corresponderão o máximo possível. Portanto /^.*abc/ corresponderia “qualquer coisa que seja algo abc”. Adicionando o quantificador não-greedy ? faz com que o regex corresponda apenas a “qualquer coisa que seja”.

Como apontaram @Jared Ng e @Issun, a chave para resolver esse tipo de RegEx como “combinar tudo com uma certa palavra ou substring” ou “combinar tudo depois de uma certa palavra ou substring” é chamada de “lookaround” de asserções de comprimento zero. . Leia mais sobre eles aqui.

No seu caso particular, isso pode ser resolvido com um olhar positivo à frente. Uma imagem vale mais que mil palavras. Veja a explicação detalhada na imagem.

Regex101 Screenshot

O que você precisa é olhar em torno de asserção como .+? (?=abc) .+? (?=abc) .

Veja: Asserções Lookahead e Lookbehind Zero-Length

Esteja ciente de que [abc] não é o mesmo que abc . Parênteses internos não é uma string – cada caractere é apenas uma das possibilidades. Fora dos suportes, torna-se a corda.

Isso fará sentido sobre o regex.

  1. A palavra exata pode ser obtida no seguinte comando regex:

(“(. *?)”) / g

Aqui, podemos obter a palavra exata globalmente que está dentro das aspas duplas. Por exemplo, se o nosso texto de pesquisa for,

Este é o exemplo de palavras “duplas citadas”

então nós vamos receber “double quoted” dessa sentença.

Para regex em Java, e acredito também na maioria dos mecanismos de regex, se você quiser include a última parte, isso funcionará:

 .+?(abc) 

Por exemplo, nesta linha:

 I have this very nice senabctence 

selecione todos os caracteres até “abc” e também inclua abc

usando nosso regex, o resultado será: I have this very nice senabc

Teste isso: https://regex101.com/r/mX51ru/1

Eu acredito que você precisa de subexpressões. Se bem me lembro, você pode usar os colchetes normais () para subexpressões.

Esta parte é De grep manual:

  Back References and Subexpressions The back-reference \n, where n is a single digit, matches the substring previously matched by the nth parenthesized subexpression of the regular expression. 

Faça algo como ^[^(abc)] deve fazer o truque.

O $ marca o fim de uma string, então algo como isto deveria funcionar: [[^abc]*]$ onde você está procurando por qualquer coisa que NÃO SE TERMINA em qualquer iteração de abc , mas teria que ser no final

Além disso, se você estiver usando uma linguagem de script com regex (como php ou js), eles terão uma function de pesquisa que para quando encontrar um padrão (e você pode especificar iniciar a partir da esquerda ou iniciar da direita ou php, você pode fazer um implode para espelhar a string).

tente isso

 .+?efg 

Inquerir :

 select REGEXP_REPLACE ('abcdefghijklmn','.+?efg', '') FROM dual; 

saída:

 hijklmn