J'essaie d'écrire une déclaration regex en Python avec un motif négatif. Je veux faire correspondre un modèle qui ne commence pas par un U suivi d'un W et se termine éventuellement par un 1. Voici quelques exemples.

TUW1TH > # regex does not get applied
JUWRG > # regex does not get applied
BUIUW1 > # regex does not get applied
ATWKO > ATW KO # regex applies and space is added after the W
EWRG > E WRG # regex applies and space is added after the W
AGDTWSD > AGDTW SD # regex applies and space is added after the W

Voici la déclaration regex que j'ai essayé d'utiliser:

 re.sub(ur"[^U]W[^?1]", ur"W ", word)
2
RoberJimmer 7 mars 2016 à 03:16

3 réponses

Meilleure réponse

Je pense que vous demandez de faire correspondre un «W» éventuellement suivi d'un «1», mais uniquement si le «W» n'est pas précédé d'un «U». Si tel est le cas, un "regard négatif derrière" est la réponse:

import re

testcases = ['TUW1TH', 'JUWRG', 'BUIUW1', 'ATWKO', 'EWRG', 'AGDTWSD', 'W1EF', 'EW1RG']

# The `(W1?)` part matches a 'W' with an optional '1'. The `(?<!U)` part 
#     matches the current position only if it wasn't a preceded by a 'U'
pattern = re.compile(r'(?<!U)(W1?)')

for s in testcases:
    print(pattern.sub(r'\1 ', s))

Les sorties:

TUW1TH
JUWRG
BUIUW1
ATW KO
EW RG
AGDTW SD
W1 EF
EW1 RG

Remarque: [^U] ne fonctionne pas au début d'une ligne.

2
RootTwo 7 mars 2016 à 03:39

Essayez le modèle d'expression régulière ([^U])W1?' et utilisez-le avec re.sub() avec une substitution qui fait référence au groupe capturé, comme ceci:

import re

pattern = re.compile(r'([^U]W)1?')
for s in 'TUW1TH', 'JUWRG', 'BUIUW1', 'ATWKO', 'EWRG', 'AGDTWSD':
    print(pattern.sub(r'\1 ', s))

Sortie

TUW1TH
JUWRG
BUIUW1
ATW KO
EW RG
AGDTW SD

Notez que la sortie pour 'EWRG' diffère de votre échantillon ... Je pense que c'est une faute de frappe dans votre question?

Votre question n'était pas claire sur ce qu'il fallait faire avec le 1 facultatif suivant le W et il n'y avait aucun échantillon à démontrer. Le 1 doit-il être supprimé ou conservé? Le code ci-dessus perdra le 1:

>>> print(pattern.sub(r'\1 ', 'TW1TH'))
TW TH

Si vous vouliez que la sortie inclue le 1, vous pouvez changer le modèle d'expression régulière en r'([^U]W)(1?)' pour ajouter un deuxième groupe de capture pour le 1 facultatif, et changer la substitution en r {{ X3}}:

>>> re.sub(r'([^U]W)(1?)', r'\1 \2', 'TW1TH')
'TW 1TH'
0
mhawke 7 mars 2016 à 00:56

On dirait que vous voulez [^U]W1?

Vous avez utilisé une classe de caractères contenant "non?", Au lieu du jeton "éventuellement un 1".

0
Chris Kitching 7 mars 2016 à 00:25