Passen Sie alles außer den angegebenen Zeichenfolgen an

118

Ich weiß, dass der folgende reguläre Ausdruck mit "rot", "grün" oder "blau" übereinstimmt.

red|green|blue

Gibt es eine einfache Möglichkeit, alles mit Ausnahme mehrerer angegebener Zeichenfolgen abzugleichen?

Alfred
quelle
1
Dies können nicht alle Varianten regulärer Ausdrücke. In welcher Umgebung arbeiten Sie? Java? Perl? .NETZ? Eine C / C ++ - Regex-Bibliothek? Ein RDBMS?
FrustratedWithFormsDesigner
8
Sie sagen nicht, wofür Sie es wollen, aber Sie könnten einfach den Sinn der "Match" -Operation umkehren. Dies hilft Ihnen nicht, wenn Sie versuchen, die nicht übereinstimmenden Teile zu extrahieren. Um jedoch zu testen, ob eine ausgeschlossene Zeichenfolge nicht vorhanden ist, funktioniert dies: if (!s.match(/red|green|blue/)) ... Hinweis: Ich weiß, dass das OP nicht angibt, welche Sprache / welches Framework verwendet wird Das Vorstehende sollte als allgemeines Beispiel betrachtet werden, nicht als vorgeschriebenes.
Tvanfosson

Antworten:

152

Wenn Sie sicherstellen möchten, dass die Zeichenfolge weder rot, grün noch blau ist, lautet die Antwort von caskey. Was jedoch oft gewünscht wird, ist sicherzustellen, dass die Linie nirgendwo Rot, Grün oder Blau enthält. Verankern Sie dazu den regulären Ausdruck mit ^und fügen Sie ihn .*in den negativen Lookahead ein:

^(?!.*(red|green|blue))

Angenommen, Sie möchten Zeilen mit dem Wort "Engine", jedoch ohne eine dieser Farben:

^(?!.*(red|green|blue)).*engine

Sie könnten denken, Sie können das .*auf den Kopf des regulären Ausdrucks setzen:

^.*(?!red|green|blue)engine     # Does not work

aber du kannst nicht. Sie müssen beide Instanzen haben, damit .*es funktioniert.

Wayne Conrad
quelle
48

Hängt von der Sprache ab, aber es gibt im Allgemeinen negative Behauptungen, die Sie so einfügen können:

(?!red|green|blue)

(Vielen Dank für die Syntaxkorrektur, die oben genannten ist gültig Java und Perl, YMMV)

Caskey
quelle
2
@caskey, Die vollständige Antwort ist eine Kombination aus meiner und Ihrer. Wenn Sie sie zusammenführen möchten, lösche ich meine.
Wayne Conrad
13
Diese Antwort wäre viel nützlicher, wenn Sie sie ein wenig erklären würden. Zum Beispiel: Was machen "?" und "!" bedeuten? Warum brauchen Sie Erfassungsgruppen?
Lii
Es ist auch gültiges Python.
Joe Mornin
habe dies gerade mit der Delphi regEx Bibliothek verwendet und es funktioniert nur so: ^ (?! rot | grün | blau). Gilt auch zum Testen auf regex101.com . Fehlt dem obigen Tippfehler ein ^ oder funktioniert es tatsächlich so in Java / Perl / Python?
Peter
31

Alles andere als gegebene Saiten

Wenn Sie die gesamte Zeichenfolge abgleichen möchten, wobei Sie alles außer bestimmten Zeichenfolgen abgleichen möchten, können Sie dies folgendermaßen tun:

^(?!(red|green|blue)$).*$

Das heißt, starten Sie die Übereinstimmung am Anfang der Zeichenfolge, wo sie nicht mit Rot, Grün oder Blau beginnen und enden kann, und passen Sie alles andere an das Ende der Zeichenfolge an.

Sie können es hier versuchen: https://regex101.com/r/rMbYHz/2

Beachten Sie, dass dies nur mit Regex-Engines funktioniert, die einen negativen Lookahead unterstützen .

Sam
quelle
23

Du brauchst keinen negativen Lookahead. Es gibt ein Arbeitsbeispiel:

/([\s\S]*?)(red|green|blue|)/g

Beschreibung:

  • [\s\S] - mit einem beliebigen Zeichen übereinstimmen
  • * - Übereinstimmung von 0 bis unbegrenzt von der vorherigen Gruppe
  • ? - so wenig wie möglich passen
  • (red|green|blue|) - einem dieser Wörter oder nichts entsprechen
  • g - Muster wiederholen

Beispiel:

whiteredwhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredwhiteredwhiteredwhiteredwhiteredwhiteredgreenbluewhiteredwhiteredwhiteredwhiteredwhiteredredgreenredgreenredgreenredgreenredgreenbluewhiteredbluewhiteredbluewhiteredbluewhiteredbluewhiteredwhite

Wird sein:

whitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhite

Probier es aus: regex101.com

hlcs
quelle
4
Sie können die Schrittzahl drastisch reduzieren, indem Sie [\ s \ S] gegen einen Punkt tauschen. Ich war sehr verwirrt, warum anscheinend jedes andere Beispiel jedes Wort einzeln erfasst. Dieser Weg ist etwas mehr Regex-Schritte, erfordert aber weit weniger Nachbearbeitung.
Zatronium
3
Dies führt jedoch nicht zu einem Abgleich (Textüberprüfung), sondern entfernt nur den angegebenen Text während der Ersetzung.
Marek R
Diese Lösung gibt den letzten Textblock nach den bekannten Wörtern nicht aus. Es ist also nicht nötig, die Geschwindigkeit zu vergleichen, es ist einfach falsch.
Wiktor Stribiżew
@ WiktorStribiżew behoben.
hlcs
10

Ich hatte die gleiche Frage, die vorgeschlagenen Lösungen funktionierten fast, aber sie hatten einige Probleme. Am Ende ist der reguläre Ausdruck, den ich verwendet habe:

^(?!red|green|blue).*

Ich habe es in Javascript und .NET getestet.

. * sollte nicht wie folgt in den negativen Lookahead eingefügt werden: ^ (?!. * red | green | blue), sonst würde sich das erste Element anders verhalten als die anderen (dh "anotherred" würde nicht übereinstimmen, während " anothergreen "würde)

Durden81
quelle
3

Das Anpassen eines beliebigen Textes, der jedoch einem Muster entspricht, wird normalerweise durch Teilen der Zeichenfolge mit dem Regex-Muster erreicht .

Beispiele :

  • - Regex.Split(text, @"red|green|blue")oder, um leere Werte loszuwerden Regex.Split(text, @"red|green|blue").Where(x => !string.IsNullOrEmpty(x))(siehe Demo )
  • - Regex.Split(text, "red|green|blue")oder, um leere Elemente zu entfernen Regex.Split(text, "red|green|blue").Where(Function(s) Not String.IsNullOrWhitespace(s))(siehe Demo oder diese Demo, in der LINQ unterstützt wird)
  • - text.split(/red|green|blue/)(hier muss kein gModifikator verwendet werden!) (um leere Werte zu entfernen, verwenden Sie text.split(/red|green|blue/).filter(Boolean)), siehe Demo
  • - text.split("red|green|blue"), oder - um alle nachfolgenden leeren Elemente beizubehalten - verwenden Sie text.split("red|green|blue", -1)oder um alle leeren Elemente zu entfernen, verwenden Sie mehr Code, um sie zu entfernen (siehe Demo ).
  • - Ähnlich wie bei Java, text.split(/red|green|blue/)um alle nachfolgenden Elemente zu verwenden text.split(/red|green|blue/, -1)und alle leeren Elemente zu entfernen text.split(/red|green|blue/).findAll {it != ""})(siehe Demo ).
  • - text.split(Regex("red|green|blue"))oder, leere Elemente zu entfernen, die Verwendung text.split(Regex("red|green|blue")).filter{ !it.isBlank() }finden Sie Demo
  • - text.split("red|green|blue")oder um alle nachfolgenden leeren Elemente beizubehalten, verwenden Sie text.split("red|green|blue", -1)und entfernen Sie alle leeren Elemente, verwenden Sie text.split("red|green|blue").filter(_.nonEmpty)(siehe Demo )
  • - text.split(/red|green|blue/), um leere Werte loszuwerden, verwenden Sie .split(/red|green|blue/).reject(&:empty?)(und um sowohl führende als auch nachfolgende leere Elemente zu erhalten, verwenden Sie -1als zweites Argument .split(/red|green|blue/, -1)) (siehe Demo )
  • - my @result1 = split /red|green|blue/, $text;oder mit allen nachfolgenden leeren Elementen my @result2 = split /red|green|blue/, $text, -1;oder ohne leere Elemente my @result3 = grep { /\S/ } split /red|green|blue/, $text;(siehe Demo )
  • - preg_split('~red|green|blue~', $text)oder preg_split('~red|green|blue~', $text, -1, PREG_SPLIT_NO_EMPTY)um keine leeren Elemente auszugeben (siehe Demo )
  • - re.split(r'red|green|blue', text)oder, um leere Gegenstände zu entfernen list(filter(None, re.split(r'red|green|blue', text)))(siehe Demo )
  • - Verwenden regexp.MustCompile("red|green|blue").Split(text, -1)Sie diesen Code , und wenn Sie leere Elemente entfernen müssen, verwenden Sie diesen Code . Siehe Go-Demo .

HINWEIS : Wenn Sie Muster enthalten einfangenden Gruppen , regex Split - Funktionen / Methoden können sich anders verhalten, auch auf zusätzliche Optionen abhängig. Bitte lesen Sie dann die entsprechende Dokumentation zur Split-Methode.

Wiktor Stribiżew
quelle
0

Alle außer dem Wort "rot"

var href = '(text-1) (red) (text-3) (text-4) (text-5)';

var test = href.replace(/\((\b(?!red\b)[\s\S]*?)\)/g, testF); 

function testF(match, p1, p2, offset, str_full) {
  p1 = "-"+p1+"-";
  return p1;
}

console.log(test);

Alle außer dem Wort "rot"

var href = '(text-1) (frede) (text-3) (text-4) (text-5)';

var test = href.replace(/\(([\s\S]*?)\)/g, testF); 

function testF(match, p1, p2, offset, str_full) {
  p1 = p1.replace(/red/g, '');
  p1 = "-"+p1+"-";
  return p1;
}

console.log(test);

Юрий Светлов
quelle