Welchen Unterschied macht es, ein Wort mit / ohne nachgestelltem Leerzeichen abzugleichen?


12

Ich lerne Shell-Scripting und benutze dafür den HackerRank. Es gibt eine Frage, die sich sedauf die gleiche Site bezieht : 'Sed' Befehl # 1 :

Transformieren Sie für jede Zeile in einer bestimmten Eingabedatei das erste Vorkommen des Wortes 'the' mit 'this'. Bei der Suche und Transformation muss die Groß- und Kleinschreibung beachtet werden.

Zunächst habe ich versucht,

sed 's/the/this/'

aber in diesem Beispiel ist der Testfall fehlgeschlagen. Dann habe ich es versucht

sed 's/the /this /'

und es hat funktioniert. Es stellt sich also die Frage, welchen Unterschied die Leerzeichen gemacht haben. Vermisse ich hier etwas?


Ich gehe davon aus, dass die erste Version auch "funktioniert" hat, aber nicht wie erwartet. Es hätte das erste Vorkommen der Buchstabenfolge "the" ersetzen sollen, aber Sie haben sich wahrscheinlich das erste Vorkommen des Wortes "the" angesehen.
Dubu

Nun, in dieser Theorie ja, in der Praxis nein.
Rolf

Antworten:


7

Der Unterschied besteht darin, ob theim Eingabetext ein Leerzeichen nach steht .
Zum Beispiel:

Bei einem Satz ohne Leerzeichen kein Ersatz:

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

Funktioniert mit einem Satz mit einem Leerzeichen wie erwartet:

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

Bei einem Satz mit einem anderen Leerzeichen erfolgt keine Ersetzung:

$ echo -e 'the\tman' | sed 's/the /this /'
the     man

Das habe ich vermisst. Ich musste "the" als String nehmen. Kein Teilstring.
JHA

1
@JHA: Es kommt auch auf das Ende einer Zeile an. ZB könnte das Wort "the" am Ende einer Zeile als Teil einer Datei mit Zeilenumbruch erscheinen, sich aber immer noch in der Mitte eines Absatzes befinden und somit immer noch ein normales Wort in einem englischen Satz sein. the( |$)könnte näher an der Arbeit sein, wenn das Extended Regex funktioniert. Wie auch immer, IDK was du meinst "als String" vs. Teilstring. In beiden Fällen handelt es sich um einen Teil der gesamten Zeile, und Ihre Testfälle reichen nicht aus, um die Fälle zu erkennen, in denen ein Fehler auftritt "the ". Kusalanadas Antwort ist bedeutend besser. Ich würde empfehlen, sie zu akzeptieren.
Peter Cordes

20

Dies ist eine kostengünstige und fehleranfällige Methode für die Worterkennung .

Beachten Sie, dass theein Leerzeichen nach dem Wort nicht mit dem Wort therebyübereinstimmt. Wenn Sie also ein Leerzeichen nach dem Wort theeinfügen, wird vermieden, dass diese Zeichenfolge am Wortanfang übereinstimmt . Dies ist jedoch immer noch der Fall überein bathe(wenn ein Leerzeichen folgt), und es stimmt nichtthe am Ende einer Zeile überein .

Um eine thekorrekte Übereinstimmung mit dem Wort (oder einem anderen Wort) zu erzielen, sollten Sie keine Leerzeichen um das Wort verwenden, da dies verhindern würde, dass das Wort am Anfang oder Ende von Zeilen übereinstimmt oder von einem anderen Nicht-Wort-Zeichen flankiert wird, z B. Interpunktions- oder Tabulatorzeichen.

Verwenden Sie stattdessen ein Wortbegrenzungsmuster mit der Breite Null:

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

Das \<und \>entspricht den Grenzen vor und nach dem Wort, dh dem Abstand zwischen einem Wortzeichen und a Nichtwortzeichen . Ein Wortzeichen ist im Allgemeinen ein beliebiges Zeichen [[:alnum:]_](oder[A-Za-z0-9_] in der POSIX-Ländereinstellung) .

Mit GNU sedkönnen Sie auch \banstelle von \<und Folgendes verwenden \>:

sed 's/\bthe\b/this/'

7

sed arbeitet mit regulären Ausdrücken. Verwendensed 's/the /this /' Sie einfach das Leerzeichen nachthe Teil des übereinstimmenden Musters.

Mit sed 's/the/this/'ersetzen Sie alle Vorkommen von themitthis unabhängig davon , ob ein Raum nach existiertthe .

In der HackerRank-Übung ist das Ergebnis dasselbe, weil es logisch ist, das durch das zu ersetzen ... Sie ersetzen nur ein Pro-Nomen, dem standardmäßig ein Leerzeichen folgt (Grammatikregeln).

Sie können den Unterschied erkennen, wenn Sie beispielsweise versuchen, thedas Wort in Großbuchstaben zu schreiben 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.

Danke für die Antwort. Geschätzt :)
JHA

"Sie ersetzen alle Vorkommen" Um es klar auszudrücken: Ohne den gnach dem Ersetzungstext ersetzen Sie nur das erste Vorkommen.
Dubu
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.