Expression régulière pour rechercher uniquement en majuscules “mots”, avec quelques exceptions
J'ai des chaînes de caractères suivantes:
"The thing P1 must connect to the J236 thing in the Foo position."
Je voudrais correspondre avec une expression régulière seulement ceux en majuscules les mots (à savoir ici P1
et J236
). Le problème est que je ne veux pas correspondre à la première lettre de la phrase quand il s'agit d'une lettre mot.
Exemple, dans:
"A thing P1 must connect ..."
Je veux P1
seulement, pas A
et P1
. En faisant cela, je sais que je peux manquer d'un vrai "mot" (comme dans "X must connect to Y"
), mais je peux vivre avec ça.
En outre, je ne veux pas de match en majuscules les mots si la phrase est en majuscule.
Exemple:
"THING P1 MUST CONNECT TO X2."
Bien sûr, idéalement, je voudrais correspondre les mots techniques P1
et X2
ici mais comme ils sont "cachés" dans la phrase en majuscules et puisque ces mots n'ont pas de modèle spécifique, c'est impossible. Encore une fois je peux vivre avec ça parce que les majuscules phrases ne sont pas si fréquents dans mes fichiers.
Merci!
- Faire de tous les termes techniques contiennent des nombres?
- Quoi que vous fassiez, ne pas utiliser de 7 bits littéraux aime
[A-Z]
. C'est très RADIX-50, et n'a pas sa place dans le code écrit au cours des dernières décennies. Utiliser quelque chose qui fonctionne sur n'importe quel texte. Peu ce qui signifie quelque chose lié à\w
ou[[:alpha:]]
ou\pL
ou\p{Alphabetic}
, selon votre expression rationnelle du langage et de l'environnement. En fait, les implémentations varient tellement que certains de ceux-ci peut être légale et de droit, sur certaines plateformes, mais légal et mal sur les autres.
Vous devez vous connecter pour publier un commentaire.
Dans une certaine mesure, cela va varier en fonction de la "saveur" de la RegEx que vous utilisez. La liste suivante est basée sur .NET RegEx, qui utilise
\b
pour les limites des mots. Dans le dernier exemple, il utilise aussi négatif lookaround(?<!)
et(?!)
ainsi que de non-capture de parenthèses(?:)
En fait, toutefois, si les conditions toujours contenir au moins une lettre majuscule suivie par au moins un numéro, vous pouvez utiliser
De majuscules et de chiffres (le total doit être de 2 ou plus):
De majuscules et de chiffres, mais en commençant par au moins une lettre:
L'ancêtre, pour retourner les articles qui ont n'importe quelle combinaison de lettres majuscules et de chiffres, mais qui ne sont pas d'une seule lettre au début d'une ligne et qui ne font pas partie d'une ligne qui est tout en majuscules:
ventilation:
La regex commence avec
(?:
. Le?:
signifie que, bien que ce qui suit est entre parenthèses, je ne suis pas intéressé par la capture du résultat. Cela s'appelle le "non-capture de parenthèses." Ici, je suis en utilisant le paretheses parce que je suis à l'aide de l'alternance (voir ci-dessous).À l'intérieur de la non-capture de parens, j'ai deux clauses séparées, séparés par le symbole
|
. C'est l'alternance -- comme un "ou". La regex peut correspondre à la première expression ou la seconde. Les deux cas sont ici "c'est le premier mot de la ligne" ou "tout ce," parce que nous avons l'exigence spéciale de l'exclusion des mots d'une lettre au début de la ligne.Maintenant, regardons chaque expression dans l'alternance.
La première expression est:
(?<!^)[A-Z]\b
. La proposition principale ici est[A-Z]\b
, qui est une lettre majuscule suivie par une frontière de mot, ce qui pourrait être des signes de ponctuation, espaces, saut de ligne, etc. La partie avant qui est(?<!^)
, qui est un "négatif lookbehind." C'est un zéro-largeur de l'assertion, ce qui signifie qu'il n'est pas "consommer" des personnages dans le cadre d'un match -- pas vraiment important de comprendre qu'ici. La syntaxe pour le négatif lookbehind dans .NET est(?<!x)
, où x est l'expression qui doit pas exister avant notre proposition principale. Ici, cette expression est tout simplement^
, ou au début de la ligne, donc de ce côté de l'alternance se traduit par "n'importe quel mot composé d'une seule lettre majuscule qui est pas au début de la ligne."Ok, donc nous sommes correspondant à une lettre, majuscule les mots qui ne sont pas au début de la ligne. Nous avons encore besoin de faire correspondre les mots composées de tous les numéros et les lettres majuscules.
Qui est gérée par une partie relativement petite de la seconde expression dans l'alternance:
\b[A-Z0-9]+\b
. Le\b
s représentent les limites des mots, et la[A-Z0-9]+
correspond à un ou plusieurs chiffres et de lettres majuscules ensemble.Le reste de l'expression se compose d'autres lookarounds.
(?<!^[A-Z0-9 ]*)
est l'autre négative lookbehind, où l'expression est^[A-Z0-9 ]*
. Cela signifie que ce qui précède ne doit pas être en lettres majuscules et de chiffres.La deuxième lookaround est
(?![A-Z0-9 ]$)
, qui est une anticipation négatif. Cela signifie ce qui suit doit pas être en lettres majuscules et de chiffres.Donc, au total, nous sommes à la capture des mots de toutes les lettres majuscules et de chiffres, et à l'exclusion d'une lettre, majuscule des caractères à partir du début de la ligne et de tout ce à partir de lignes qui sont tous en majuscules.
Il y a au moins une faiblesse ici dans le lookarounds dans la deuxième alternance expression agir de façon indépendante, ainsi, une phrase comme "Un P1 doit se connecter à la J9" correspond à J9, mais pas P1, parce que tout ce qui est avant P1 est en majuscule.
Il est possible de contourner ce problème, mais ce serait presque le triple de la longueur de la regex. En essayant de faire beaucoup en une seule regex est rarement, sinon jamais, justfied. Vous serez mieux de diviser le travail en plusieurs regexes ou une combinaison de regex et la norme de la chaîne de traitement des commandes dans votre langage de programmation de choix.
(?<!^[A-Z0-9]*)
La*
signifie zéro ou plus, par opposition à+
, qui est utilisé ailleurs et désigne un ou plus. Le début-de-ligne est notée par^
, donc, si ce qui précède n'est que le début-de-ligne et ZÉRO ou plusieurs lettres majuscules ou des chiffres, le match échoue.A
pas de match. Si vous n'êtes pas préoccupé par tous les bouchons de phrases, le deuxième alinéa peut être réduit à(?:^[A-Z0-9]{2,}|(?<!^)\b[A-Z0-9]+)\b
. Ici, la première partie de l'alternance correspond au début de la ligne, et le nom doit être de 2 ou plus de bouchons ou des nums. La deuxième partie de l'alternance des matchs partout PAS au début de la ligne.\)
au lieu de(:?
et)
2.\<
pour bigin de la parole et de\>
de limite de mot, au lieu de\b
de limite de mot.Pourquoi avez-vous besoin de faire cela dans un monster-regex? Vous pouvez utiliser le code pour mettre en œuvre certaines de ces règles, et de le faire serait d'autant plus facile à modifier si ces exigences changer plus tard.
Par exemple:
Peut-être que vous pouvez exécuter cette regex en premier pour voir si la ligne est tout en majuscule:
Qui correspond seulement si c'est une ligne comme
THING P1 MUST CONNECT TO X2.
Sinon, vous devriez être en mesure de sortir de la personne en majuscules phrases avec ceci:
Qui doit correspondre à "P1" et "J236" dans
The thing P1 must connect to the J236 thing in the Foo position.
/^[A-Z\d\W_]*$/
Ne fais pas les choses comme [A-Z] ou [0-9]. N' \p{Lu} et \d à la place. Bien entendu, ceci est valable pour perl en fonction regex saveurs. Cela inclut java.
Je voudrais suggérer que vous ne faites pas quelque énorme regex. D'abord diviser le texte en phrases. ensuite, marquer c' (divisé en mots). Utiliser une regex pour vérifier chaque jeton/mot. Passez le premier élément de la phrase. Vérifier si tous les pions sont en lettres majuscules à l'avance et de passer l'ensemble de la phrase, si oui, ou de modifier la regex dans ce cas.
Je ne suis pas une regex gourou par tous les moyens. Mais essayez:
Je ne vais pas essayer pour les points de bonus, de l'entier supérieur le cas de la phrase. hehe
Pour le premier cas, vous proposer, vous pouvez utiliser: '[[:blank:]]+[A-Z0-9]+[[:blank:]]+', par exemple:
echo "La chose P1 doit se connecter à la J236 chose dans le Foo position" | grep -oE '[[:blank:]]+[A-Z0-9]+[[:blank:]]+'
Dans le second cas, peut-être vous avez besoin d'utiliser quelque chose d'autre et non pas d'une expression régulière, peut-être un script avec un dictionnaire de mots techniques...
Acclamations, Fernando