0
votes

Regex pour trouver des mots contenant des permutations de lettres, avec une lettre obligatoire, et pas d'autre

Nous avons une table mysql avec une colonne qui a du texte alphanumérique. Nous avons un cas d'utilisation unique où nous devons trouver toutes les rangées de la table où cette colonne contient du texte contenant:

  • Une lettre à coup sûr, disons s
  • plus une ou plusieurs d'autres lettres, disons T, A, C, N (les lettres peuvent être dans une commande et répétées autant de fois)
  • ne contient aucune autre lettre autre que les S et le T, A, C, N

    En tant que tel, celles-ci seraient ok: xxx

    celles-ci ne seraient pas ok: xxx

    Nous avons essayé quelque chose comme ça, mais cela ne fonctionne pas: xxx


4 commentaires

À ma connaissance, des looks négatifs ne sont pas pris en charge dans MySQL, mais même si cela l'a fait, appliquer un opérateur de répétition à une construction à l'avenir de largeur zéro n'a pas de sens. La construction de look-avance n'envoie pas la position de la chaîne, afin d'appliquer plusieurs fois que plusieurs fois seraient simplement en train de tourner les roues. Même si cela soutenait le regard, il semble que ce schéma particulier soit un comportement indéfini.


Il n'est pas clair si s pourrait apparaître plusieurs fois ou non. Est scanns ou nscas d'accord?


Sonne à moi comme ^ [tacn] * [S] [Stacn] * $


@BobbleBubble qui ne satisfait pas la condition "une ou plusieurs" des autres lettres. Votre modèle correspond à une chaîne de S .


3 Réponses :


0
votes

Utilisez cette réégalité pour la correspondance de modèle:

pattern = "^(S+[TACN]+S*[TACN]*)+$|^(S*[TACN]+S+[TACN]*)+$"


4 commentaires

Ceci n'est pas cohérent. Il correspond ncsans mais pas scanns . Cela implique que si une réapparition à un réapparaît du tout qu'il doit réapparaître au début ou à la fin de la séquence dans le même ordre que le premier match. En d'autres termes, il applique une restriction inutile sur le motif.


Pour la situation du multiple: Ce modèle fera le tour, s'il vous plaît vérifier: motif = "^ (S + [tacn] + s *) + $ | ^ (S * [tacn] + s +) + $". Mis à jour les ANS ci-dessus aussi


Cela ne parvient toujours pas à faire correspondre le cas avec S intégré dans une chaîne valide mais pas sur les extrémités, comme anstc .


Belle prise. Mise à jour du motif de regex: motif = "^ (s + [tacn] + s * [tacn] *) + $ | ^ (tacn] + s + [tacn] *) + $"



2
votes

Ceci suppose que s code> peut apparaître plusieurs fois comme les autres caractères autorisés. Les exigences n'excluent pas explicitement cette possibilité, bien que les exemples n'incluent pas un tel exemple. Je n'interprète pas "une lettre à coup sûr" de dire "apparaît une seule fois".

^(s+[tacn][stacn]*|[tacn]+s[stacn]*)$


2 commentaires

Merci. Oui, s peut répéter aussi bien. Votre code ne semble pas fonctionner cependant. Il ne trouve aucun enregistrement.


Étrange, car quand je branche mon motif dans Nick's dbfiddle (la même réponse que vous avez acceptée) Je reçois précisément les mêmes résultats. Je l'ai testé et ça marche bien. Je pense que peut-être que vous n'êtes pas copié et la collant correctement. Je n'ai pas cuillère à la cuillère alimenter tous les détails comme Nick, mais cela devrait fonctionner correctement s'il est mis en œuvre correctement.



4
votes

mysql 8.0.4 +

de mysql 8.0.4 à partir de MySQL 8.0.4, MYSQL REGEXP Support modifié à la bibliothèque ICU et les regards sont pris en charge. Pour ces versions, cette regex répondra à vos exigences: xxx

Il utilise 3 lookaheads:

  1. (? =. * s) affirme qu'il y a un s dans la chaîne;
  2. (? =. * [acnt]) affirme y a au moins l'un des [acnt] dans la chaîne;
  3. (?!. * [^ acnst]) affirme qu'il n'y a pas de caractères autres que [acnst] dans la chaîne.

    Démo sur dbfiddle

    mysql avant 8,0,4

    Cette regex vous donnera les résultats que vous souhaitez: xxx

    il cherche soit < / p>

    • an s précédé de zéro ou plus de [tacn] et suivi d'un ou plusieurs de [tacn] ; ou
    • an s précédé d'un ou de plusieurs [tacn] et suivi de zéro ou plus de [tacn]

      Query: xxx

      sortie: xxx

      Démo sur dbfiddle

      Si vous souhaitez autoriser s . qu'une fois, il suffit de changer la regex vers xxx

      ceci modifie le résultat pour STS à 1 , tout en laissant le résultat pour ss comme 0 car il ne contient pas de caractère autre que s .

      Démo sur dbfiddle


2 commentaires

Merci pour le patient et explication détaillée!


@Khomnazid aucun souci. Je suis heureux d'avoir pu aider.