1
votes

regex ne fonctionne pas correctement lorsque le test est correct

Pour ma base de données, j'ai une liste de numéros d'entreprise dont certains commencent par deux lettres. J'ai créé un regex qui devrait les éliminer d'une requête et selon mes tests, cela devrait. Mais une fois exécuté, le résultat contient toujours les nombres avec des lettres.

Voici mon regex, que j'ai testé sur https : //www.regexpal.com

SELECT companyNumber FROM company_data 
WHERE companyNumber ~ '([^A-Z+|a-z+].*)' order by companyNumber desc

Je l'ai testé contre de nombreuses variantes telles que SC08093, ZC000191 et NI232312 qui ne devraient pas correspondre et ne t dans les tests, ce qui est bien.

Ma requête sql ressemble à;

([^A-Z+|a-z+].*)

Pour résumer, les chaînes comme SC08093 ne doivent pas correspondre car elles commencent par lettres.

J'ai lu la documentation de postgres mais je n'ai rien trouvé à ce sujet. Je ne suis pas sûr de ce qui me manque ici. Merci.


3 commentaires

Essayez WHERE companyNumber PAS SIMILAIRE À '[A-Za-z] {2}%'


Merci, cela a fonctionné. Si vous le pouvez, pourriez-vous expliquer pourquoi cela a fonctionné et mon regex n'a peut-être pas fonctionné?


Votre expression régulière ne fait probablement pas ce que vous avez l'intention - [^ A-Z + | a-z +] correspondra à un caractère unique qui n'est ni une lettre minuscule ni une lettre majuscule ni un littéral + ni un littéral '|' .


3 Réponses :


2
votes

Ne pas commencer par une lettre peut être fait avec

WHERE company ~ '^[^A-Za-z].*'

demo: db fiddle

Le premier ^ marque le début. Le [^ A-Za-z] dit "pas de lettre" (y compris les lettres minuscules et majuscules).


Modifier: Modifié [Az] dans le [A-Za-z] plus précis ( Pourquoi cette expression régulière autorise-t-elle un signe curseur? )


2 commentaires

[^ A-z] ne signifie pas réellement aucune lettre. Cela signifie pas de lettre, [ \,], ^, _ et `chars . Consultez la [A-z] char range .


@ WiktorStribiżew oui, bien sûr, vous avez raison. Dans ce cas, l'autre solution est également erronée car elle commence toujours par un chiffre. C'est quand le TO no définit exactement son cas d'utilisation.



4
votes

Le ~ '([^ A-Z + | a-z +]. *)' ne fonctionne pas car il s'agit d'un [^ A-Z + | a-z +]. * opération de correspondance d'expression régulière qui retourne true même en cas de correspondance partielle (l'opération de correspondance d'expression régulière ne nécessite pas de correspondance complète de chaîne, et donc le modèle peut correspondre n'importe où dans la chaîne). [^ A-Z + | a-z +]. * correspond à une lettre de A à Z , +, | ou une lettre de a à z`, puis n'importe quelle quantité de zéro ou plusieurs caractères, n'importe où dans une chaîne.

Vous pouvez utiliser

WHERE companyNumber NOT SIMILAR TO '[A-Za-z]{2}%'

Voir la démo en ligne

Ici, NOT SIMILAR TO renvoie le résultat inverse de SIMILAR TO opération. Cet opérateur SIMILAR TO accepte des modèles qui sont presque des modèles de regex, mais qui sont également comme des modèles de caractères génériques normaux. PAS SIMILAIRE À '[A-Za-z] {2}%' signifie tous les enregistrements commençant par deux lettres ASCII ( [A-Za-z] {2} ) et ayant quelque chose après (% ) ne sont PAS retournés et tous les autres seront retournés. Notez que SIMILAR TO nécessite une correspondance de chaîne complète, identique à LIKE.


3 commentaires

Merci, cela a fonctionné. Si vous le pouvez, pourriez-vous expliquer pourquoi cela a fonctionné et mon regex n'a peut-être pas fonctionné?


@KieranDee J'espère avoir ajouté suffisamment de détails. Je pense que SIMILAR TO est la meilleure solution pour votre tâche. Si vos conditions deviennent plus spécifiques, vous pouvez envisager de passer à l'opérateur ~ . Ensuite, n'oubliez pas ^ pour marquer le début de la chaîne et au cas où vous en auriez besoin, $ comme fin de l'ancre de chaîne.


Merci pour vos explications. Donc, même si une partie de la chaîne correspond à l'expression régulière, postgres la retournera essentiellement. Cela signifie que je dois faire correspondre la chaîne entière avec l'expression régulière plutôt qu'une partie de celle-ci, du moins pour mon expression régulière.



2
votes

Votre modèle: [^ A-Z + | a-z +]. * signifie "une chaîne où au moins certains caractères ne sont pas AZ" - pour étendre cela à toute la chaîne, vous devez utiliser une expression régulière ancrée comme indiqué par S-Man (le groupe défini avec (..) n'est pas vraiment nécessaire btw)

J'utiliserais probablement une expression régulière qui spécifie que le modèle valide est et puis utilisez ! ~ à la place.

where not (company ~ '^[0-9].*$')

^ [0-9]. * $ signifie "se compose uniquement de nombres "et le ! ~ signifie" ne correspond pas "

ou

where company !~ '^[0-9].*$'


0 commentaires