Regex pour faire correspondre la chaîne contenant deux noms dans n'importe quel ordre


180

J'ai besoin d'un ET logique dans regex.

quelque chose comme

jack et james

d'accord avec les chaînes suivantes

  • 'Salut Jack, voici James '

  • 'Salut James, voici Jack '



@AndersonGreen, la question était prématurément verrouillée. Les réponses manquent cruellement car ces solutions ne sont pas viables car la plupart des regex ne reconnaissent pas la recherche et le quantificateur de mode . Je crois que le quantificateur existait au moment où la question était posée.
XPMai

Réponses:


261

Vous pouvez effectuer des vérifications en utilisant des lookarounds :

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

Essaye-le.

Cette approche présente l'avantage de pouvoir spécifier facilement plusieurs conditions.

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

18
Quelqu'un voudrait-il expliquer un peu plus en détail comment cet exemple fonctionne?
bjmc

2
vimsyntaxe: ^\(.*\<jack\>\)\@=\(.*\<james\>\@=\).*$or\v^(.*<jack>)@=(.*<james>)@=.*$
mykhal

Est-ce que quelqu'un sait pourquoi cela se briserait (au moins en JavaScript) lorsque j'essaie de rechercher des chaînes commençant par «#»? ^(?=.*\b#friday\b)(?=.*\b#tgif\b).*$ne correspond pas blah #tgif blah #friday blahmais ^(?=.*\bfriday\b)(?=.*\btgif\b).*$fonctionne très bien.
btleffler

2
Que \bsignifie ici?
VarunAgw


106

Essayer:

james.*jack

Si vous voulez les deux en même temps, alors orles:

james.*jack|jack.*james

1
La réponse acceptée a fonctionné. cela a également parfaitement fonctionné pour moi. Pour rechercher du code dans Visual Studio, «trouver des résultats».
Yogurt The Wise

1
Celui-ci fonctionne pour moi et est beaucoup plus concis et facile à comprendre que la réponse acceptée!
Kumar Manish

1
J'avais besoin d'une solution qui n'avait que deux noms pour correspondre, donc cette réponse est plus concise pour ce cas. Mais la réponse acceptée devient plus concise au-delà de 2 puisque le nombre de "ou" augmente factoriellement. Pour 3 noms, il y aurait 6 "ou" s, 4 noms seraient 24 "ou" s, etc.
WileCau

Je recommanderais de le rendre paresseux james.*?jack|jack.*?james. Cela aidera sur les gros textes.
Jekis

42

Explication de la commande que je vais écrire : -

. signifie n'importe quel caractère, chiffre peut remplacer.

* signifie zéro ou plusieurs occurrences de chose écrite juste avant.

|signifie «ou» .

Alors,

james.*jack

chercherait james , puis n'importe quel nombre de caractères jusqu'à ce que jackvient.

Puisque vous voulez soit jack.*jamesoujames.*jack

D'où la commande :

jack.*james|james.*jack

7
En passant, vous pourriez aussi avoir édité la réponse de @ icyrock (qui est la même que la vôtre, à peine 6 ans plus tôt), votre explication est très utile en soi.
WoJ

2
Merci pour cette réponse, je ressens cependant le besoin de préciser que dans la recherche VSCode, votre réponse jack. * James | james. * jack prendra les espaces entre les '|' (ou) symbole en considération lors de la recherche. jack. * james | james. * jack fonctionne et ne cherche pas les espaces
jgritten

2
IF $ _explanation === "génial" ALORS retournez $ THUMBS_UP ENDIF;
Syed Aqeel



2

Vim a un opérateur de succursale \& qui est utile lors de la recherche d'une ligne contenant un ensemble de mots, dans n'importe quel ordre. De plus, étendre l'ensemble des mots requis est trivial.

Par exemple,

/.*jack\&.*james

correspondra à une ligne contenant jacket james, dans n'importe quel ordre.

Consultez cette réponse pour plus d'informations sur l'utilisation. Je ne connais aucune autre saveur regex qui implémente le branchement; l'opérateur n'est même pas documenté sur l' entrée wikipedia Expression régulière .


2

MÉTHODE 1: Un jacket unjames

Juste au cas où deux jackou deux jamesne seraient pas autorisés, un seul jacket un jamesseraient valides, nous pouvons probablement concevoir une expression similaire à:

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

Ici, nous exclurions ces instances de paires en utilisant ces instructions:

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

et,

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

Démo RegEx 1

Nous pouvons également simplifier cela pour,

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

Démo RegEx 2


Si vous souhaitez simplifier / modifier / explorer l'expression, cela a été expliqué dans le panneau supérieur droit de regex101.com . Si vous le souhaitez, vous pouvez également regarder dans ce lien , comment il correspondrait à certains exemples d'entrées.


Circuit RegEx

jex.im visualise les expressions régulières:

entrez la description de l'image ici

Tester

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}`);
    });
}


MÉTHODE 2: Un jacket un jamesdans un ordre spécifique

Il peut également être conçu pour le premier jamesdernier jack, similaire au suivant:

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

Démo RegEx 3

et vice versa:

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

Démo RegEx 4


0

Vous pouvez utiliser la fonction de quantification de regex car elle lookaroundpeut ne pas être prise en charge tout le temps.

(\b(james|jack)\b.*){2,}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.