Que diferença faz corresponder uma palavra com / sem um espaço em branco à direita?

12

Estou aprendendo scripts de shell e por isso estou usando o HackerRank. Há uma pergunta relacionada ao sedmesmo site: Comando 'Sed' # 1 :

Para cada linha em um determinado arquivo de entrada, transforme a primeira ocorrência da palavra 'the' com 'this'. A pesquisa e transformação devem ser estritamente sensíveis a maiúsculas e minúsculas.

Primeiro de tudo eu tentei,

sed 's/the/this/'

mas nesse caso de teste de amostra falhou. Então eu tentei

sed 's/the /this /'

e funcionou. Então, surge a questão de que diferença os espaços em branco criaram? Estou faltando alguma coisa aqui?

JAI
fonte
Presumo que a primeira versão também "funcionou", mas não como o esperado. Deveria ter substituído a primeira ocorrência da sequência de letras "the", mas você provavelmente observou a primeira ocorrência da palavra "the".
Dubu
Bem, nesta teoria, sim, na prática, não.
Rolf

Respostas:

7

A diferença é se existe um espaço depois theno texto de entrada.
Por exemplo:

Com uma frase sem espaço , não há substituição:

$ echo 'theman' | sed 's/the /this /'
theman

Com uma frase com um espaço , funciona conforme o esperado:

$ echo 'the man' | sed 's/the /this /'
this man

Com uma frase com outro caractere de espaço em branco , nenhuma substituição ocorrerá:

$ echo -e 'the\tman' | sed 's/the /this /'
the     man
BDR
fonte
Eu senti falta disso. Eu tive que pegar "o" como uma corda. Não é uma substring.
JAI
1
@ JAI: Isso também importa no final de uma linha. por exemplo, a palavra "the" pode aparecer no final de uma linha como parte de um arquivo com quebra de linha, mas ainda estar no meio de um parágrafo e, portanto, ser uma palavra normal em uma frase em inglês. the( |$)pode estar mais perto de funcionar, se esse regex estendido funcionar. Enfim, identifique o que você quer dizer "como uma string" versus substring. Nos dois casos, é uma substring de toda a linha, e seus casos de teste são insuficientes para detectar os casos em que "the "falha. A resposta de Kusalanada é significativamente melhor, eu recomendo aceitá-la.
Peter Cordes
20

É uma maneira barata e propensa a erros de correspondência de palavras .

Observe que, thecom um espaço após ele não corresponde à palavra thereby, a correspondência com um espaço após theevita a correspondência dessa sequência no início das palavras. No entanto, ainda não coincidir com bathe(se for seguido por um espaço), e ele não corresponder the, no final de uma linha.

Para corresponder a palavra thecorretamente (ou qualquer outra palavra), você não deve usar espaços ao redor da palavra, pois isso impediria a correspondência no início ou no final das linhas ou se for flanqueada por outro caractere que não seja uma palavra, como qualquer pontuação ou caractere de tabulação, por exemplo.

Em vez disso, use um padrão de limite de palavra com largura zero:

sed 's/\<the\>/this/'

O \<e \>corresponde aos limites antes e depois da palavra, ou seja, o espaço entre um caractere de palavra e um caractere que não é uma palavra . Um caractere de palavra geralmente corresponde a qualquer caractere [[:alnum:]_](ou [A-Za-z0-9_]no código do idioma POSIX).

Com o GNU sed, você também pode usar \bno lugar de \<e \>:

sed 's/\bthe\b/this/'
Kusalananda
fonte
7

sed trabalha com expressões regulares. Se sed 's/the /this /'você usar apenas faça o espaço após theparte do padrão correspondente.

Usando sed 's/the/this/'você substituir todas as ocorrências thecom thisnão importa se existe um espaço depois the.

No exercício HackerRank, o resultado é o mesmo, porque substituir o com isso é lógico ... você substitui apenas um pró-substantivo que, por padrão, é seguido pelo espaço (regras gramaticais).

Você pode ver a diferença se tentar, por exemplo, capitalizar thena palavra the theater:

echo 'the theater' |sed 's/the /THE /g'
THE theater                              
#theater is ignored since the is not followed by space

echo 'the theater' |sed 's/the/THE/g'
THE THEater
#both the are capitalized.
George Vasiliou
fonte
Obrigado pela resposta. Apreciado :)
JHA
"você substitui todas as ocorrências" Para ficar claro: sem o gtexto após a substituição, você substitui apenas a primeira ocorrência.
Dubu