Wie kann ich mit Saiten, die nicht mit einem bestimmten Muster in Perl?
Ich weiß, es ist einfach zu passen, also alles außer einem bestimmten Charakter mit einem regulären Ausdruck.
$text = "ab ac ad";
$text =~ s/[^c]*//g; # Match anything, except c.
$text is now "c".
Ich weiß nicht, wie man "außer" Zeichenfolgen anstelle von Zeichen. Wie würde ich "match nichts, außer 'ac'" ? Versucht, [^- (ac)] und [^"ac"], ohne Erfolg.
Ist es überhaupt möglich?
Für einfache "string ist (nicht) enthalten, die in anderen Zeichenfolge" es ist besser, verwenden Sie einen index (gibt -1 zurück, wenn es nicht enthalten). Ich schrieb einen mailserver log-Datei-parser ein, die zuerst verwendet regexp für diejenigen, die einfach überprüft, nachdem ich umgestellt auf index () - es Laufzeit wurde reduziert um über 25% gegenüber dem regexp-version. Als bonus-index() ist leichter zu Lesen.
Was ist dein Ziel genau? (1) eine Zeichenfolge suchen, die nicht enthalten
Hinzufügen @Bart ' s Kommentar: Bitte geben Sie exsamples: (1) die Zeichenfolge, die Sie wollen, zu überprüfen und zu entkräften, ODER (2) Zeichenfolge, die Sie möchten, zu extrahieren, aus diesem string ODER (3) das Ergebnis der Ersetzungen in diesem string.
Ich habe versucht, zu vereinfachen, das Beispiel, aber mein eigentliches Ziel war, zu reinigen, einige wiki-markup. Im Grunde entfernen Sie alle {{...}} nicht enthalten "}}" drin.
Ein einfaches Beispiel ist gut, aber stellen Sie sicher, dass Sie nicht übermäßig vereinfachen—Ihr Beispiel sollte noch sein Vertreter das problem, das Sie lösen wollen.
Was ist dein Ziel genau? (1) eine Zeichenfolge suchen, die nicht enthalten
ac
(oder eine andere sub-string) oder (2) alles ersetzen in einem string mit Ausnahme der sub-string ac
(z.B. ändern abacadac
in acac
)? Ich vermute, es ist das letztere.Hinzufügen @Bart ' s Kommentar: Bitte geben Sie exsamples: (1) die Zeichenfolge, die Sie wollen, zu überprüfen und zu entkräften, ODER (2) Zeichenfolge, die Sie möchten, zu extrahieren, aus diesem string ODER (3) das Ergebnis der Ersetzungen in diesem string.
Ich habe versucht, zu vereinfachen, das Beispiel, aber mein eigentliches Ziel war, zu reinigen, einige wiki-markup. Im Grunde entfernen Sie alle {{...}} nicht enthalten "}}" drin.
Ein einfaches Beispiel ist gut, aber stellen Sie sicher, dass Sie nicht übermäßig vereinfachen—Ihr Beispiel sollte noch sein Vertreter das problem, das Sie lösen wollen.
InformationsquelleAutor ssn | 2010-01-21
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den folgenden löst sich die Frage verstanden im zweiten Sinne beschrieben in Bart K. Kommentar:
Auch
'abacadac'
->'acac'
Es sollte jedoch darauf hingewiesen werden, dass in den meisten praktischen Anwendungen negativen lookaheads erweisen sich als mehr als nützlich, diesen Ansatz.
Danke 🙂 (gleiche Grenze hier)
Mich zu schlagen :-). Eine leichte Verbesserung könnte sein, zu tun, s/(\bak\b)/./\1/g, was bedeutet, 'ac fac ac' -> acac
Ich dachte, der weniger kreative Muster:
a([^c]|$)|(^|[^a])c|[^ac]
InformationsquelleAutor Antony Hatchkins
Wenn Sie nur wollen, um zu überprüfen, ob der string nicht enthalten, "ac", benutzen Sie einfach eine negation.
oder
InformationsquelleAutor Christoffer Hammarström
@ssn,
Ein paar Kommentare zu deiner Frage:
"#" ist.
der "*" dort. "[^c]" bedeutet, dass die
Charakter-Klasse aus allen
Zeichen außer den Buchstaben "c".
Dann verwenden Sie die /g-modifier,
also alle solche Vorkommnisse im text
ersetzt (in deinem Beispiel mit
nichts). Die "null oder mehr" ("*")
Modifikator ist daher überflüssig.
Bitte Lesen Sie die Dokumentation auf Charakter-Klassen(Siehe "perldoc perlre" in die Befehlszeile, oder online unter http://perldoc.perl.org/perlre.html ) - Sie werden sehen, es besagt, dass für die Liste der Zeichen innerhalb der eckigen Klammern des RE "die Entsprechung ein beliebiges Zeichen aus der Liste". Bedeutung Reihenfolge ist nicht relevant und es gibt keine "strings", nur eine Liste von Zeichen. "()" und doppelte Anführungszeichen auch haben keine spezielle Bedeutung innerhalb der eckigen Klammern.
Ich bin mir jetzt nicht genau sicher, warum Sie sprechen über matching aber dann gibt Sie ein Beispiel der substitution. Aber um zu sehen, ob ein string nicht mit der sub-Strings "ac", die Sie gerade brauchen, um Sie zu negieren das match:
Sagen, Sie haben eine Zeichenfolge von text in die eingebettet sind mehrere vorkommen einer Teilzeichenfolge. Wenn Sie nur wollen, dass der text rund um die sub-string, entfernen Sie einfach alle vorkommen des sub-string:
Möchte man auch die reverse - entfernen allen text außer für alle vorkommen der sub-string, ich würde vorschlagen, etwas wie:
Diesem Grunde zählt die Anzahl der Zeiten, die die sub-string wird in das Textfeld und Drucke der sub-string, der die Anzahl der Zeiten, die mit dem "x" - operator. Nicht sehr elegant, ich bin mir sicher, dass ein Perl-guru könnte kommen mit etwas besser.
@ennuikiller:
Dies ist falsch, denn es generiert eine Warnung ("Nutzlose Verwendung von negativen Muster verbindlich (!~) in void context") unter "Warnungen" und tut nichts außer entfernen Sie alle Teilstrings "ac" aus dem text, die sein könnte mehr einfach so geschrieben, wie ich oben schrieb:
InformationsquelleAutor Offer Kaye
Update: In einem Kommentar auf Ihre Frage, die Sie erwähnt, die Sie reinigen wollen, wiki-markup und entfernen ausgewogene Sequenzen von
{{
...}}
. Abschnitt 6 der Perl-FAQ deckt diese: Kann ich mit Perl reguläre Ausdrücke zum suchen nach ausgewogenen text?Betrachten Sie das folgende Programm:
Seinen Ausgang:
Für Ihre speziellen Beispiel könnte
Ist, löschen Sie nur eine
a
oderc
wenn Sie nicht Teil einerac
Sequenz.Dies ist im Allgemeinen schwierig zu tun, mit einem regulären Ausdruck.
Sagen, Sie wollen nicht
foo
gefolgt von optionalen Leerzeichen und dannbar
im$str
. Oft ist es übersichtlicher und einfacher ist GESONDERT zu prüfen. Zum Beispiel:Könnten Sie auch interessieren eine Antwort auf eine ähnliche Frage, wo ich schrieb
Zu verstehen, die Komplikation, Lesen Wie Regexes Arbeit von Mark Dominus. Das Modul kompiliert regulären Ausdrücke in state machines. Wenn es Zeit ist zu entsprechen, es füttert den Eingabe-string, der die state-Maschine und prüft, ob der state-Maschine endet in einem akzeptieren Zustand. So schließen Sie eine Zeichenfolge, müssen Sie angeben, eine Maschine, die akzeptiert werden alle Eingänge mit Ausnahme einer bestimmten Reihenfolge.
Was helfen könnte, ist ein
/v
regulären Ausdruck wechseln, erstellt die state machine wie gewohnt, aber dann ergänzt Sie die accept-state-bit für alle Staaten. Es ist schwer zu sagen, ob sich diese wirklich nützlich sein, wie im Vergleich mit separaten Prüfungen, weil ein/v
regulären Ausdruck kann immer noch überraschen die Menschen, nur in unterschiedlicher Weise.Wenn Sie Interesse an den theoretischen details siehe Eine Einführung in Formale Sprachen und Automaten von Peter Linz.
InformationsquelleAutor Greg Bacon
können Sie die Verwendung von index()
InformationsquelleAutor ghostdog74
Können Sie leicht ändern Sie das regex-für Ihren Zweck.
Meine Meinung geändert - das funktioniert nicht aus dem gleichen Grund, dass die anderen Lösungen, die hier gepostet wird nicht funktionieren: es wird entfernen Sie die c. Versuchen Sie das "einfache änderung" in einen vollständigen test und sehen, was passiert.
Frage war: "Spiel nichts, außer 'ac'". Mit der Entfernung von ^$ in meiner regex, es würde mit etwas, Haltestelle 'ac'.
OK, tut mir Leid. Dann habe ich völlig falsch verstanden, die Frage, sorry. Ich dachte, er wollte ersetzen Sie den gesamten string, nicht nur den Anfang. Mein schlechtes.
InformationsquelleAutor Alexandr Ciornii