Mon programme ressemble à ceci:
Traceback (most recent call last): File "<input>", line 1, in <module> File "/home/swfarnsworth/programs/pycharm-2019.2/helpers/pydev/_pydev_bundle/pydev_umd.py", line 197, in runfile pydev_imports.execfile(filename, global_vars, local_vars) # execute the script File "/home/swfarnsworth/programs/pycharm-2019.2/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile exec(compile(contents+"\n", file, 'exec'), glob, loc) File "/home/swfarnsworth/projects/medaCy/medacy/tools/converters/con_to_brat.py", line 255, in <module> content = convert_con_to_brat(full_file_path) File "/home/swfarnsworth/projects/my_file.py", line 191, in convert_con_to_brat start_ind = get_absolute_index(text_lines, d["start_ind"], d["data_item"]) File "/home/swfarnsworth/projects/my_file.py", line 122, in get_absolute_index entity_pattern_spaced = re.sub(r"\\\s+", r"\s+", entity_pattern_escaped) File "/usr/local/lib/python3.7/re.py", line 192, in sub return _compile(pattern, flags).sub(repl, string, count) File "/usr/local/lib/python3.7/re.py", line 309, in _subx template = _compile_repl(template, pattern) File "/usr/local/lib/python3.7/re.py", line 300, in _compile_repl return sre_parse.parse_template(repl, pattern) File "/usr/local/lib/python3.7/sre_parse.py", line 1024, in parse_template raise s.error('bad escape %s' % this, len(this)) re.error: bad escape \s at position 0
L'erreur est la suivante:
import re # Escape the string, in case it happens to have re metacharacters my_str = "The quick brown fox jumped" escaped_str = re.escape(my_str) # "The\\ quick\\ brown\\ fox\\ jumped" # Replace escaped space patterns with a generic white space pattern spaced_pattern = re.sub(r"\\\s+", r"\s+", escaped_str) # Raises error
J'obtiens cette erreur même si je supprime les deux barres obliques inverses avant le '\s+'
ou si je transforme la chaîne brute ( r"\\\s+"
) en une chaîne régulière. J'ai vérifié la documentation Python 3.7 et il semble que \s
soit toujours la séquence d'échappement pour les espaces blancs.
4 Réponses :
Je suppose que vous essayez de faire:
The\s+quick\s+brown\s+fox\s+jumped
import re # Escape the string, in case it happens to have re metacharacters my_str = "The\\ quick\\ brown\\ fox\\ jumped" print(re.sub(r"\s+", "s+", my_str))
Si vous souhaitez avoir un \ s + littéral, essayez cette réponse ou peut-être:
The\s+quick\s+brown\s+fox\s+jumped
import re # Escape the string, in case it happens to have re metacharacters my_str = "The\\ quick\\ brown\\ fox\\ jumped" escaped_str = re.escape(my_str) print(re.sub(r"\\\\\\\s+", re.escape(r"\s") + '+', escaped_str))
Ou peut-être:
The quick brown fox jumped
import re # Escape the string, in case it happens to have re metacharacters my_str = "The\\ quick\\ brown\\ fox\\ jumped" escaped_str = re.escape(my_str) # "The\\ quick\\ brown\\ fox\\ jumped" # Replace escaped space patterns with a generic white space pattern print(re.sub(r"\\\\\\\s+", " ", escaped_str))
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.
jex.im visualise les expressions régulières:
Je pense qu'il veut obtenir un \s+
littéral dans le résultat.
Essayez de jouer avec les barres obliques inverses pour éviter que l'expression régulière essaie d'interpréter \s
:
import warnings warnings.warn('bad escape %s' % this, DeprecationWarning, stacklevel=4)
maintenant
else: try: this = chr(ESCAPES[this][1]) except KeyError: if c in ASCIILETTERS: raise s.error('bad escape %s' % this, len(this))
Il semble que python essaie d'interpréter \s
comme il interpréterait r"\n"
au lieu de le laisser seul comme Python le fait normalement. Si tu fais. Par exemple:
The +quick +brown +fox +jumped
donne:
re.sub(r"\\\s+", r"\n+", escaped_str)
même si \n
était utilisé dans une chaîne brute.
Le changement a été introduit dans le problème n ° 27030: les échappements inconnus composés de '\'
et de lettres ASCII dans les expressions régulières sont désormais des erreurs .
Le code qui effectue le remplacement est dans sre_parse.py
(python 3.7):
>>> spaced_pattern 'The\\s+quick\\s+brown\\s+fox\\s+jumped' >>> print(spaced_pattern) The\s+quick\s+brown\s+fox\s+jumped
Ce code recherche ce qui se cache derrière un littéral \
et essaie de le remplacer par le caractère non-ascii approprié. De toute évidence, s
n'est pas dans le dictionnaire ESCAPES
donc l'exception KeyError
est déclenchée, puis le message que vous recevez.
Sur les versions précédentes, il venait d'émettre un avertissement:
spaced_pattern = re.sub(r"\\\s+", "\\\s+", escaped_str)
On dirait que nous ne sommes pas seuls à souffrir de la mise à niveau de la version 3.6 à 3.7: https://github.com/gi0baro/weppy/issues/227
Les moteurs Regex se comportent de la même manière (principalement) en ce qui concerne les chaînes de remplacement
qui leur sont remis.
Ils essaient d'insérer le code de contrôle équivalent aux caractères échappés, comme les tabulations crlf, etc ...
Toute séquence d'échappement qu'il ne reconnaît pas, elle supprime simplement la fuite.
Donné
spaced_pattern = re.sub(r"\\\s+", r"\s+", escaped_str)
le r"\s+"
remet au moteur cette chaîne de remplacement \s+
.
Puisqu'il n'y a pas une telle séquence d'échappement, cela supprime simplement l'évasion
et insère s+
en position de remplacement.
Vous pouvez le voir ici https://regex101.com/r/42QCvi/1
Il n'y a pas d'erreur, mais cela devrait l'être puisque vous n'obtenez pas ce que vous pensez devoir.
En réalité, une évasion littérale doit toujours être échappée
comme on peut le voir ici https://regex101.com/r/bzQgfN/1
Rien de nouveau, ils disent juste que c'est une erreur, mais c'est vraiment un avertissement de notification
que vous n'obtenez pas ce que vous pensez.
Cela fait des années et des années. Parfois, c'est une erreur, parfois non.
"Cela fait des années et des années. Parfois, c'est une erreur, parfois non." Attends quoi? J'ai eu du mal avec ces évasions, et maintenant tu me dis que je ne suis pas fou après tout?
Essayez simplement d' import regex as re
au lieu d' import re
.
Lorsque j'utilise votre code, avec
entity_pattern_escaped
changé enescaped_str
, puisprint(spaced_pattern)
produitThe\s+quick\s+brown\s+fox\s+jumped
qui ressemble au résultat souhaité.Je peux reproduire sur 3.7
Je n'ai pas pu reproduire en 3.6.3, mais cela échoue sur ideone.com qui est 3.7.3.
Il y a apparemment eu un changement dans la façon dont la chaîne de remplacement est traitée dans 3.7.
@Bramar, j'ai corrigé mon exemple de code
@SteeleFarnsworth: À propos de votre question (supprimée) " Comment puis-je implémenter une nouvelle classe Python dans l'interpréteur cpython? ": J'ai remarqué que smth manquait dans _collectionmodule.c .
@CristiFati J'ai pu découvrir la source de l'erreur; N'hésitez pas à me contacter à swfarnsworth@gmail.com si vous souhaitez quand même en discuter.