1
votes

Python 3.7.4: 're.error: bad escape \ s à la position 0'

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.


7 commentaires

Lorsque j'utilise votre code, avec entity_pattern_escaped changé en escaped_str , puis print(spaced_pattern) produit The\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.


4 Réponses :


-1
votes

Je suppose que vous essayez de faire:

The\s+quick\s+brown\s+fox\s+jumped

Sortie 1

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

Sortie 2

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

Sortie 3

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.


Circuit RegEx

jex.im visualise les expressions régulières:

entrez la description de l'image ici

Démo


1 commentaires

Je pense qu'il veut obtenir un \s+ littéral dans le résultat.



5
votes

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))

Mais pourquoi?

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


0 commentaires

1
votes

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.


1 commentaires

"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?



0
votes

Essayez simplement d' import regex as re au lieu d' import re .


0 commentaires