Regex für eine Zeichenfolge mit zwei Namen in beliebiger Reihenfolge

179

Ich brauche logisches UND in Regex.

etwas wie

Jack AND James

stimme den folgenden Zeichenfolgen zu

  • "Hallo Jack hier ist James "

  • "Hallo James hier ist Jack "

Meloun
quelle
1
Mögliches Duplikat: Mehrfachwörter in beliebiger Reihenfolge mit Regex
Anderson Green
@ AndersonGreen, die Frage wurde vorzeitig gesperrt. Die Antworten fehlen stark , da diese Lösungen nicht lebensfähig sind , da die meisten Regex nicht erkennen Lookarounds und Modus quantifier . Ich glaube, der Quantifizierer existierte zum Zeitpunkt der gestellten Frage.
XPMai

Antworten:

259

Sie können Überprüfungen mithilfe von Lookarounds durchführen :

^(?=.*\bjack\b)(?=.*\bjames\b).*$

Probier es aus.

Dieser Ansatz hat den Vorteil, dass Sie problemlos mehrere Bedingungen angeben können.

^(?=.*\bjack\b)(?=.*\bjames\b)(?=.*\bjason\b)(?=.*\bjules\b).*$
Alin Purcaru
quelle
16
Würde es jemandem etwas ausmachen, etwas detaillierter zu erklären, wie dieses Beispiel funktioniert?
bjmc
2
vimSyntax: ^\(.*\<jack\>\)\@=\(.*\<james\>\@=\).*$oder\v^(.*<jack>)@=(.*<james>)@=.*$
Mykhal
Weiß jemand, warum dies (zumindest in JavaScript) nicht funktioniert, wenn ich versuche, nach Zeichenfolgen zu suchen, die mit '#' beginnen? ^(?=.*\b#friday\b)(?=.*\b#tgif\b).*$stimmt nicht überein blah #tgif blah #friday blah, ^(?=.*\bfriday\b)(?=.*\btgif\b).*$funktioniert aber einwandfrei.
Btleffler
2
Was \bbedeutet hier?
VarunAgw
1
@VarunAgw Wortgrenze . regelmäßige-
Ausdrücke.info/
104

Versuchen:

james.*jack

Wenn Sie beide gleichzeitig wollen, dann sind orsie:

james.*jack|jack.*james
icyrock.com
quelle
1
Die akzeptierte Antwort hat funktioniert. Das hat auch bei mir perfekt funktioniert. Für die Suche nach Code in Visual Studio 'Ergebnisse finden'.
Joghurt der Weise
1
Dieser funktioniert für mich und ist viel prägnanter und leichter zu verstehen als die akzeptierte Antwort!
Kumar Manish
1
Ich brauchte eine Lösung, bei der nur zwei Namen übereinstimmten, daher ist diese Antwort für diesen Fall präziser. Die akzeptierte Antwort wird jedoch über 2 hinaus präziser, da die Anzahl der "oder" s faktoriell zunimmt. Für 3 Namen gäbe es 6 "oder" s, 4 Namen wären 24 "oder" s usw.
WileCau
Ich würde empfehlen, es faul zu machen james.*?jack|jack.*?james. Dies hilft bei großen Texten.
Jekis
42

Erklärung des Befehls, den ich schreiben werde : -

. bedeutet, dass jedes Zeichen, Ziffer anstelle von kommen kann.

* bedeutet null oder mehr Vorkommen von Dingen, die unmittelbar davor geschrieben wurden.

|bedeutet "oder" .

So,

james.*jack

würde suchen james , dann eine beliebige Anzahl von Zeichen bis jackkommt.

Da willst du entweder jack.*jamesoderjames.*jack

Daher Befehl :

jack.*james|james.*jack
Shubham Sharma
quelle
7
Als Randnotiz: Sie hätten auch die Antwort von @ icyrock bearbeiten können (die dieselbe ist wie Ihre, nur 6 Jahre zuvor). Ihre Erklärung ist für sich genommen sehr nützlich.
WoJ
2
Vielen Dank für diese Antwort. Ich möchte jedoch darauf hinweisen, dass bei der VSCode-Suche Ihre Antwortbuchse . * James | james. * jack nimmt die Leerzeichen zwischen dem '|' (oder) Symbol bei der Suche berücksichtigt. jack. * james | james. * jack funktioniert und sucht nicht nach den Leerzeichen
jgritten
2
IF $ _explanation === "awesome" THEN return $ THUMBS_UP ENDIF;
Syed Aqeel
9

Es ist kurz und süß

(?=.*jack)(?=.*james)
Shivam Agrawal
quelle
6

Du kannst tun:

\bjack\b.*\bjames\b|\bjames\b.*\bjack\b
Codaddict
quelle
2

Vim verfügt über einen Verzweigungsoperator \&, der bei der Suche nach einer Zeile mit einer Reihe von Wörtern in beliebiger Reihenfolge hilfreich ist. Darüber hinaus ist das Erweitern des Satzes erforderlicher Wörter trivial.

Beispielsweise,

/.*jack\&.*james

stimmt mit einer Zeile überein, die jackund jamesin beliebiger Reihenfolge enthält.

Weitere Informationen zur Verwendung finden Sie in dieser Antwort . Mir ist kein anderer Regex-Geschmack bekannt, der eine Verzweigung implementiert. Der Operator ist nicht einmal im Wikipedia-Eintrag für reguläre Ausdrücke dokumentiert .

Firstrock
quelle
2

Methode 1: Eins jackund Einsjames

Nur für den Fall, dass zwei jackoder zwei jamesnicht erlaubt sind, nur eins jackund eins jamesgültig sind, können wir wahrscheinlich einen Ausdruck entwerfen, der ähnlich ist wie:

^(?!.*\bjack\b.*\bjack\b)(?!.*\bjames\b.*\bjames\b)(?=.*\bjames\b)(?=.*\bjack\b).*$

Hier würden wir diese Paarinstanzen mit den folgenden Anweisungen ausschließen:

(?!.*\bjack\b.*\bjack\b)

und,

(?!.*\bjames\b.*\bjames\b)

RegEx Demo 1

Wir können das auch vereinfachen,

^(?!.*\bjack\b.*\bjack\b|.*\bjames\b.*\bjames\b)(?=.*\bjames\b|.*\bjack\b).*$

RegEx Demo 2


Wenn Sie den Ausdruck vereinfachen / ändern / untersuchen möchten, wurde dies im oberen rechten Bereich von regex101.com erläutert . Wenn Sie möchten , können Sie in diesem Link auch sehen , wie es mit einigen Beispieleingaben übereinstimmt.


RegEx Circuit

jex.im visualisiert reguläre Ausdrücke:

Geben Sie hier die Bildbeschreibung ein

Prüfung

const regex = /^(?!.*\bjack\b.*\bjack\b|.*\bjames\b.*\bjames\b)(?=.*\bjames\b|.*\bjack\b).*$/gm;
const str = `hi jack here is james
hi james here is jack
hi james jack here is jack james
hi jack james here is james jack
hi jack jack here is jack james
hi james james here is james jack
hi jack jack jack here is james
`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}


Methode 2: Eins jackund Eins jamesin einer bestimmten Reihenfolge

Es kann auch für das erste bis jamesletzte entworfen werden jack, ähnlich dem folgenden:

^(?!.*\bjack\b.*\bjack\b|.*\bjames\b.*\bjames\b)(?=.*\bjames\b.*\bjack\b).*$

RegEx Demo 3

und umgekehrt:

^(?!.*\bjack\b.*\bjack\b|.*\bjames\b.*\bjames\b)(?=.*\bjack\b.*\bjames\b).*$

RegEx Demo 4

Emma
quelle
0

Sie können die Quantifiziererfunktion von Regex verwenden, da diese lookaroundmöglicherweise nicht immer unterstützt wird.

(\b(james|jack)\b.*){2,}
XPMai
quelle