Expression Régulière Pour Les Mots En Double Consécutifs
Je suis un débutant d'expression régulière, et je n'arrive pas à comprendre comment écrire une seule expression régulière qui "correspondrait" à des mots consécutifs en double tels que:
Paris dans Le printemps.
Pas que est liée.
Pourquoi riez-vous? Les expressions régulières mes sont-elles si mauvaises??
Existe-t-il une seule expression régulière qui correspondra à toutes les chaînes en gras ci-dessus?
12 réponses
Essayez cette expression régulière:
\b(\w+)\s+\1\b
Ici \b
est une limite de mot et \1
fait référence à la correspondance capturée du premier groupe.
Je crois que cette expression rationnelle gère plus de situations:
/(\b\S+\b)\s+\b\1\b/
Une bonne sélection de chaînes de test peut être trouvée ici: http://callumacrae.github.com/regex-tuesday/challenge1.html
La bibliothèque PCRE largement utilisée peut gérer de telles situations (vous n'obtiendrez pas la même chose avec les moteurs regex compatibles POSIX, cependant):
(\b\w+\b)\W+\1
Essayez ceci avec re ci-dessous
- \ B début du mot limite de mot
- \W+ tout caractère de mot
- \1 LE MÊME mot correspond déjà
- \ b fin du mot
-
() * répéter à nouveau
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(); }
Non. C'est une grammaire irrégulière. Il peut y avoir des expressions régulières spécifiques au moteur/à la langue que vous pouvez utiliser, mais il n'y a pas d'expression régulière universelle qui peut le faire.
L'exemple en Javascript: les bonnes parties peuvent être adaptées pour faire ceci:
var doubled_words = /([A-Za-z\u00C0-\u1FFF\u2800-\uFFFD]+)\s+\1(?:\s|$)/gi;
\B utilise \w pour les limites de mots, où \w est équivalent à [0-9A-Z_a-z]. Si cela ne vous dérange pas cette limitation, la réponse acceptée est bonne.
C'est l'expression rationnelle que j'utilise pour supprimer les phrases en double dans mon bot twitch:
(\S+\s*)\1{2,}
(\S+\s*)
Recherche n'importe quelle chaîne de caractères qui n'est pas un espace, suivi d'un espace.
\1{2,}
Recherche ensuite plus de 2 instances de cette phrase dans la chaîne à correspondre. S'il y a 3 phrases identiques, cela correspond.
Cette expression (inspirée de Mike, ci-dessus) semble attraper tous les doublons, triplicates, etc, y compris ceux à la fin de la chaîne, ce que la plupart des autres ne font pas:
/(^|\s+)(\S+)(($|\s+)\2)+/g, "$1$2")
Je connais la question posée pour correspondre à doublons seulement, mais un triplicate est juste 2 doublons l'un à côté de l'autre:)
D'abord, je mets (^|\s+)
pour m'assurer qu'il commence par un mot complet, sinon "steak d'enfant" irait à " child'Steak "(les"s" correspondraient). Ensuite, il correspond à tous les mots ((\b\S+\b)
), suivi par un caractère de fin de chaîne ($
) ou d'un nombre de cases (\s+
), le tout répété plus d'une fois.
J'ai essayé comme ça et ça a bien fonctionné:
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
Étant donné que certains développeurs viennent sur cette page à la recherche d'une solution qui élimine non seulement les sous-chaînes consécutives Non-espaces en double, mais les triplicates et au-delà, je vais montrer le modèle adapté.
Motif: /(\b\S+)(?:\s+\1\b)+/
(Modèle Démo )
Replace: $1
(remplace la correspondance fullstring par le groupe de capture #1)
Ce modèle correspond goulûment à une sous-chaîne" entière " non-espaces, puis nécessite une ou plusieurs copies de la sous-chaîne correspondante qui peut être délimitée par un ou plusieurs espaces (espace, tabulation, saut de ligne, etc).
Plus précisément:
-
Les caractères
\b
(limite de mots) sont essentiels pour s'assurer que les mots partiels ne correspondent pas. - la deuxième parenthèse est un groupe non capturant, car cette sous-chaîne de largeur variable n'a pas besoin d'être capturée-seulement appariée/absorbée.
- le
+
(un ou plusieurs quantificateurs) sur le groupe non-Capture est plus approprié que*
Car*
"dérangera" le moteur regex pour capturer et remplacer les occurrences singleton - c'est une conception de modèle inutile.
* Remarque Si vous avez affaire à des phrases ou des chaînes d'entrée avec Ponctuation, le motif devra être affiné davantage.
Utilisez ceci au cas où vous souhaiteriez une vérification insensible à la casse des mots en double.
(?i)\\b(\\w+)\\s+\\1\\b
En voici un qui attrape plusieurs mots plusieurs fois:
(\b\w+\b)(\s+\1)+
Regex pour supprimer 2 + mots en double (mots consécutifs/non consécutifs)
Essayez cette expression rationnelle qui peut attraper 2 mots ou plus en double et ne laisser qu'un seul mot. Et les mots en double n'ont même pas besoin d'être consécutifs .
/(\b\w+\b)(?=\b.*\1\b)/ig
Ici \b
est utilisé pour la Limite de Mot, ?=
est utilisé pour l'anticipation positif, et les \1
est utilisé pour le référencement.