wake-up-neo.com

Regulärer Ausdruck für aufeinanderfolgende doppelte Wörter

Ich bin ein Anfänger im Bereich der regulären Ausdrücke, und ich kann nicht genau herausfinden, wie man einen einzelnen regulären Ausdruck schreibt, der mit doppelten aufeinander folgenden Wörtern "übereinstimmt", wie zum Beispiel:

Paris in die ... Die Frühling.

Nicht das das ist verwandt.

Warum lachen Sie? Sind mein mein reguläre Ausdrücke, die schlecht sind?

Gibt es einen einzelnen regulären Ausdruck, der mit ALLEN der obigen fettgedruckten Zeichenfolgen übereinstimmt?

98
Joshua

Versuchen Sie diesen regulären Ausdruck:

\b(\w+)\s+\1\b

Hier \b ist eine Wortgrenze und \1 verweist auf die erfasste Übereinstimmung der ersten Gruppe.

118
Gumbo

Ich glaube, dass dieser Regex mehr Situationen bewältigt:

/(\b\S+\b)\s+\b\1\b/

Eine gute Auswahl an Teststrings finden Sie hier: http://callumacrae.github.com/regex-tuesday/challenge1.html

19
Mike Viens

Die weit verbreitete PCRE-Bibliothek kann mit solchen Situationen umgehen (Sie werden jedoch nicht the dasselbe mit POSIX-kompatiblen Regex-Engines erreichen):

(\b\w+\b)\W+\1
5
soulmerge

Versuchen Sie dies mit unten RE

  • \ b Beginn der Wortgrenze
  • \ W + ein beliebiges Wortzeichen
  • \ 1 dasselbe Wort stimmt bereits überein
  • \ b Ende von Word
  • () * Nochmal wiederholen

    public static void main(String[] args) {
    
        String regex = "\\b(\\w+)(\\b\\W+\\b\\1\\b)*";//  "/* Write a RegEx matching repeated words here. */";
        Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE/* Insert the correct Pattern flag here.*/);
    
        Scanner in = new Scanner(System.in);
    
        int numSentences = Integer.parseInt(in.nextLine());
    
        while (numSentences-- > 0) {
            String input = in.nextLine();
    
            Matcher m = p.matcher(input);
    
            // Check for subsequences of input that match the compiled pattern
            while (m.find()) {
                input = input.replaceAll(m.group(0),m.group(1));
            }
    
            // Prints the modified sentence.
            System.out.println(input);
        }
    
        in.close();
    }
    
5
Faakhir

Nein, das ist eine unregelmäßige Grammatik. Möglicherweise gibt es engine-/sprachspezifische reguläre Ausdrücke, die Sie verwenden können, aber es gibt keinen universellen regulären Ausdruck, der dies ermöglicht.

Hier ist eine, die mehrere Wörter mehrfach auffängt:

(\b\w+\b)(\s+\1)+
3
synaptikon

Regex to Strip 2+ doppelte Wörter (aufeinanderfolgende/nicht aufeinanderfolgende Wörter)

Versuchen Sie es mit dieser Regex, die zwei oder mehr doppelte Wörter fängt und nur ein einziges Wort zurücklässt. Und die doppelten Wörter müssen nicht einmal aufeinanderfolgend sein .

/\b(\w+)\b(?=.*?\b\1\b)/ig

Hier, \b wird für die Wortgrenze verwendet, ?= wird für positive Vorschau verwendet, und \1 wird für die Rückreferenzierung verwendet.

BeispielQuelle

2
Niket Pathak

Dies ist der reguläre Ausdruck, mit dem ich doppelte Sätze in meinem Twitch-Bot entferne:

(\S+\s*)\1{2,}

(\S+\s*) sucht nach Zeichenfolgen, die keine Leerzeichen sind, gefolgt von Leerzeichen.

\1{2,} sucht dann nach mehr als 2 passenden Instanzen dieser Phrase in der Zeichenfolge. Wenn es 3 identische Phrasen gibt, stimmt das überein.

2
Neceros

Das Beispiel in Javascript: Die Good Parts können dazu angepasst werden:

var doubled_words = /([A-Za-z\u00C0-\u1FFF\u2800-\uFFFD]+)\s+\1(?:\s|$)/gi;

\ b verwendet\w für Wortgrenzen, wobei\w [0-9A-Z_a-z] entspricht. Wenn Ihnen diese Einschränkung nichts ausmacht, ist die akzeptierte Antwort in Ordnung.

2
Daniel

Dieser Ausdruck (inspiriert von Mike, siehe oben) scheint alle Duplikate, Dreifachpaare usw. zu erfassen, einschließlich derjenigen am Ende der Zeichenkette, die die meisten anderen nicht haben:

/(^|\s+)(\S+)(($|\s+)\2)+/g, "$1$2")

Ich kenne die Frage, die gestellt wird, um Duplikate nur zusammenzupassen, aber ein dreifaches Exemplar ist gerade 2 Duplikate nebeneinander :)

Zuerst habe ich (^|\s+) um sicherzustellen, dass es mit einem vollständigen Wort beginnt, sonst würde "child's steak" zu "child'steak" gehen (das "s" würde übereinstimmen). Dann stimmt es mit allen vollständigen Wörtern überein ((\b\S+\b)), gefolgt von einem Ende der Zeichenkette ($) oder eine Anzahl von Leerzeichen (\s+), das ganze mehr als einmal wiederholt.

Ich habe es so ausprobiert und es hat gut funktioniert:

var s = "here here here     here is ahi-ahi ahi-ahi ahi-ahi joe's joe's joe's joe's joe's the result result     result";
print( s.replace( /(\b\S+\b)(($|\s+)\1)+/g, "$1"))         
--> here is ahi-ahi joe's the result
1
Nico

Da einige Entwickler auf diese Seite kommen, um nach einer Lösung zu suchen, die nicht nur doppelte aufeinanderfolgende Nicht-Whitespace-Teilzeichenfolgen, sondern auch dreifache und darüber hinaus beseitigt, werde ich das angepasste Muster zeigen.

Muster: /(\b\S+)(?:\s+\1\b)+/ ( Muster Demo )
Ersetzen: $1 (ersetzt die Vollstring-Übereinstimmung durch Erfassungsgruppe 1)

Dieses Muster passt gierig zu einer "ganzen" Nicht-Leerraum-Teilzeichenfolge und erfordert dann eine oder mehrere Kopien der übereinstimmenden Teilzeichenfolge, die durch ein oder mehrere Leerzeichen (Leerzeichen, Tabulator, Zeilenvorschub usw.) begrenzt sein können.

Speziell:

  • \b (Wortgrenzen) -Zeichen sind wichtig, um sicherzustellen, dass Teilwörter nicht übereinstimmen.
  • Die zweite Klammer ist eine nicht erfassende Gruppe, da diese Teilzeichenfolge mit variabler Breite nicht erfasst werden muss - nur abgeglichen/absorbiert.
  • das + (ein oder mehrere Quantifizierer) für die nicht erfassende Gruppe ist geeigneter als * weil * "stört" die Regex-Engine, um einzelne Vorkommen zu erfassen und zu ersetzen - dies ist ein verschwenderisches Musterdesign.

* Hinweis: Wenn Sie mit Sätzen oder Eingabezeichenfolgen mit Interpunktion arbeiten, muss das Muster weiter verfeinert werden.

1
mickmackusa

Verwenden Sie diese Option, wenn Sie nicht zwischen Groß- und Kleinschreibung unterscheiden möchten, ob doppelte Wörter vorhanden sind.

(?i)\\b(\\w+)\\s+\\1\\b
0
Neelam

Der folgende Ausdruck sollte korrekt funktionieren, um eine beliebige Anzahl aufeinanderfolgender Wörter zu finden. Die Zuordnung kann zwischen Groß- und Kleinschreibung unterscheiden.

String regex = "\\b(\\w+)(\\s+\\1\\b)*";
Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);

Matcher m = p.matcher(input);

// Check for subsequences of input that match the compiled pattern
while (m.find()) {
     input = input.replaceAll(m.group(0), m.group(1));
}

Sample Input: Auf Wiedersehen, auf Wiedersehen, GooDbYe

Beispielausgabe: Auf Wiedersehen

Erläuterung:

Der reguläre Ausdruck:

\ b: Beginn einer Wortgrenze

\ w +: Beliebig viele Wortzeichen

(\ s +\1\b) *: Beliebige Anzahl von Leerzeichen gefolgt von Word, die mit dem vorherigen Word übereinstimmen und die Wortgrenze beenden. Ganzes in * eingewickelt hilft, mehr als eine Wiederholung zu finden.

Gruppierung:

m.group (0): Enthält die übereinstimmende Gruppe in dem obigen Fall Goodbye goodbye GooDbYe

m.group (1): Enthält das erste Wort des übereinstimmenden Musters in dem obigen Fall Goodbye

Die Ersetzungsmethode ersetzt alle aufeinanderfolgenden übereinstimmenden Wörter durch die erste Instanz des Wortes.

0
Aks789