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?
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.
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
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
Versuchen Sie dies mit unten RE
() * 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();
}
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)+
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.
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.
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.
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
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.+
(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.
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
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.