2011-04-05 05:57:20 +0000 2011-04-05 05:57:20 +0000
45
45

Correspondendo apenas à primeira ocorrência numa linha com Regex

Sou completamente novo no regex e apreciaria muito qualquer ajuda.

A tarefa é simples. Tenho um ficheiro CSV com registos assim:

12345,67890,12345,67890
12345,67890,12345,67890
12345,67890,12345,67890
12345,67890,12345,67890
12345,67890,12345,67890

Gostaria de substituir a primeira vírgula por um espaço e deixar o resto das vírgulas intactas, para cada linha. Existe alguma expressão regex que só corresponda à primeira vírgula?

Eu tentei isto: ^.....,. Isto corresponde à vírgula, no entanto, também corresponde a todo o comprimento da string que precede a vírgula, por isso se eu tentar substituir isto por um espaço todos os números são apagados também.

Respostas (6)

55
55
55
2011-04-05 06:26:54 +0000

O padrão de correspondência poderia ser:

^([^,]+),
^ starts with
[^,] anything but a comma
+ repeated one or more times (use * (means zero or more) if the first field can be empty)
([^,]+) remember that part
, followed by a comma

Em por exemplo, em perl, toda a correspondência e substituição ficaria como:

s/^([^,]+),/ /

A peça de substituição apenas pega na totalidade da correspondência e substitui-a pelo primeiro bloco de que se lembrou e anexa um espaço. O coma é “largado” porque não está no primeiro grupo de captura.

7
7
7
2012-08-01 21:31:36 +0000
s/,/ /

Isto, por defeito (isto é, sem a opção g), substitui apenas a primeira partida.

3
3
3
2011-04-05 06:26:08 +0000

Este deve corresponder apenas ao primeiro número e à vírgula: ^(\d{5}),. Se quiser devorar tudo o resto na linha, mude o regex para o seguinte: ^(\d{5}),(.*)$

2
2
2
2015-05-13 00:44:34 +0000

Uma solução mais elegante é usar a combinação preguiçosa:

s/^(.+?),/ /

que irá agrupar caracteres movendo-se do início da cadeia (^) para o final por um caracter (.+?) em cada passo até encontrar o primeiro sinal de vírgula. Todo este grupo juntamente com a primeira ocorrência de vírgula será substituído por grupo (“) e carácteres espaciais.

1
1
1
2015-02-28 21:07:59 +0000

TextPad sempre teve a capacidade de utilizar a notação posix, mas tem de alterar as definições numa caixa de diálogo diferente. Para usar as configurações padrão do TextPad para expressões regulares, tem de “escapar” aos parênteses de abertura e fecho:

Substituir espaço após o código postal de 5 dígitos, no início de cada linha

^\([0-9]+\)[]

Com o separador

\t

Como acima, o ^ significa início da linha

( é um “parêntese escapado” e marca o início da primeira expressão de pesquisa, ou seja os cinco dígitos

[0-9]+ significa um ou mais dígitos (não apenas códigos postais de 5 dígitos)

) é outro “escape parênteses” para marcar o fim da primeira expressão de pesquisa

[] é apenas um carácter de espaço (poderia deixar de fora os parênteses, mas depois ninguém conseguiria vê-lo nesta página web : -)

Na expressão de substituição

\1 é a primeira expressão de pesquisa, a parte entre parênteses acima (um ou mais dígitos)

\t é um caractere de tabulação

Então o comando de pesquisa e substituição procura um ou mais dígitos, seguido de um espaço. Depois substitui tudo isso pelo mesmo grupo de dígitos seguido por um separador.

Penso que não há forma de encontrar simplesmente “um espaço que vem depois dos 5 dígitos” para que possa simplesmente substituir o espaço sem tocar nos dígitos. Você tem de cobrir os 5 dígitos (a primeira string) seguidos do espaço (a segunda string). Depois, embora pareça redundante ou incómodo, SUBSTITUI a corda original de 5 dígitos com ITSELF, seguida do separador (a segunda corda).

Todos os que sabem disto esquecem que os novatos não fazem ideia disto. É por isso que estou a soletrar para ti, meu amigo.

Ed Poor Math Tutor e programador informático reformado de Nova Iorque

0
0
0
2019-11-26 19:24:16 +0000

Para corresponder apenas à primeira ocorrência de qualquer expressão regex, remover todas as bandeiras. Cada expressão regex vem com as seguintes bandeiras possíveis e tipicamente por defeito usa a bandeira global que irá corresponder a mais do que uma ocorrência:

  • /g = Com esta bandeira a pesquisa procura por todos os correspondências, sem ela - apenas a primeira correspondência é devolvida
  • /i = insensível a maiúsculas e minúsculas
  • /m = modo multi-linhas
  • /s = todas . para corresponder ao novo carácter de linha \n
  • /u = unicode
  • /y = sticky mode (pesquisa em localização específica)