2016-05-05 16 views
-1

Ich suche nach logischer Lösung, mit regex, so dass ich grep für pattern abfragen kann und nicht pattern2 fangen. Eine Art "Stop" oder "bis zu" Logik.Regex: grep ('Muster') fängt 'pattern2'

Bei dieser Frage geht es um die Durchführung dieser Art von Abfrage, nicht um Namenskonventionen. Ich suche keinen Workaround, nur die regexp Logik.

Aus Gründen der Argumentation, machen wir den Kontext 'up-to-Date' Ubuntu Bash. Aber was ich wirklich will, ist etwas, das nur die regexp Logik verwendet.

Eine Liste wie unten

entry  
entry1  
entry2  
entry.qualifier  
entry.qualifier2 

Pseudo-Befehl ein: grep ("entry")

Hinweis, dies, weil alle Einträge anzeigen lassen, da es keine 'Stop' Logik. Ich bin mir sicher, dass die Lösung eigentlich ziemlich einfach ist, ich habe Regex schon lange nicht mehr benutzt.

Etwas wie 'nichts nach dem Muster'?

+0

ich nicht ganz folge, kannst du ein beispiel geben? –

+0

Beispiel kommend ... – bigcodeszzer

+0

anubhava, ich bin wirklich auf der Suche nach einer rein regexp logischen Lösung, nicht einschließlich der Grep-Schalter – bigcodeszzer

Antwort

2

grep unterstützt Wortgrenze so eine reine regex basierte Antwort wäre:

grep '\bentry\b' file 

jedoch grep unterstützt auch -w Flag (Match Wörter), so dass Sie auch verwenden können:

grep -w 'entry' file 
2

Wenn Sie GNU grep verwenden, können hier die Wundbegrenzungsoperatoren \< und \> unterstützt werden. Das heißt \<entry\>.

POSIX doesn't specify beliebig \b oder \< oder -w Befehlszeilenoption. Was ist, wenn Sie grep verwenden müssen, das sie nicht hat? Das Problem kann gelöst werden, indem jede Zeile der Datei mit einem reinen regulären Ausdruck getestet wird, der vollständig übereinstimmen muss.

Angenommen, wir möchten Zeilen auswählen, die den Bezeichner entry enthalten, der keine Teilzeichenfolge eines längeren Bezeichnernamens ist. Angenommen, Bezeichner sind Zeichenketten aus englischen Buchstaben, Ziffern und Unterstrichen. Wir können dies nutzen:

grep -E '^(|.*[^A-Za-z_0-9])entry([^A-Za-z_0-9].*|)$' 

Beachten Sie, dass das gesamte Muster an beiden Enden verankert ist, so dass es vollständig eine ganze Zeile übereinstimmen müssen. Sie paßt zu jedem Vorkommen von entry welche:

  • wird entweder durch nichts voraus, oder auch durch ein nicht-Bezeichnerzeichen vorangestellt ist, möglicherweise mit anderen Zeichen vor ihm; und
  • wird entweder von nichts gefolgt, oder gefolgt von einem Zeichen ohne Kennung, möglicherweise gefolgt von anderen Zeichen.

Dieser Ansatz ist auch nützlich, wenn Sie eine bestimmte Vorstellung davon, was ein „Wort“ darstellt, die von der Definition durch die GNU grep \b oder \< Operatoren verwendet wird, unterscheidet. Angenommen, das Dateiformat ist so, dass entry123 tatsächlich zwei verschiedene Token entry und 123 ist und somit übereinstimmen muss. Jedoch muss entryabcnicht übereinstimmen. Dafür wird das GNU-Grep-Muster \bentry\b oder \<entry\> nicht helfen; es passt nicht entry123.

grep -E '^(|.*[^A-Za-z])entry([^A-Za-z].*|)$' 

Das heißt: Jedoch kann die obige Trick leicht zu arbeiten, angepasst werdenentry umgeben von nichts oder Zeichen, die keine Groß- oder Kleinbuchstaben sind. Es lohnt sich also, "in der Tasche zu bleiben".

+1

/bpattern/b ist alles, was erforderlich ist. – bigcodeszzer

+0

@bigcodeszzer Sie sind alles, was notwendig ist ** Wenn Sie GNU Grep ** verwenden. Meine Antwort gibt '\ <' and '\>' an: auch eine GNU Grep-Funktion, die dasselbe erreicht. '\ b' bedeutet" Anfang oder Ende eines Worts "woeras' \ <'ist speziell der Anfang. – Kaz

+0

Fair genug .... – bigcodeszzer