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?

89
demandé sur mickmackusa 2010-05-13 01:51:39

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.

100
répondu Gumbo 2010-05-12 21:55:01

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

18
répondu Mike Viens 2018-02-01 03:35:55

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
4
répondu soulmerge 2010-05-13 09:16:02

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();
    }
    
4
répondu Faakhir 2017-07-26 11:34:29

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.

3
répondu Ignacio Vazquez-Abrams 2010-05-12 21:53:15

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.

2
répondu Daniel 2013-04-24 21:04:03

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.

2
répondu Neceros 2015-07-18 01:17:17

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
1
répondu Nico 2018-02-01 03:58:41

É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.

1
répondu mickmackusa 2018-02-01 04:41:05

Utilisez ceci au cas où vous souhaiteriez une vérification insensible à la casse des mots en double.

(?i)\\b(\\w+)\\s+\\1\\b
0
répondu Neelam 2016-08-16 15:55:45

En voici un qui attrape plusieurs mots plusieurs fois:

(\b\w+\b)(\s+\1)+
0
répondu synaptikon 2018-03-24 00:08:05

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.

Exemple Source

0
répondu Niket Pathak 2018-07-05 11:57:15