web-dev-qa-db-fra.com

Comment puis-je échapper au code latex reçu via la saisie utilisateur?

J'ai lu une chaîne à partir d'une zone de texte GUI entrée par l'utilisateur et je la traite via pandoc . La chaîne contient des directives latex pour les mathématiques qui ont des caractères barre oblique inverse. Je veux envoyer la chaîne sous forme de chaîne brute à pandoc pour traitement. Mais quelque chose comme "\ theta" devient un onglet et "heta".

Comment puis-je convertir un littéral de chaîne contenant des barres obliques inverses en une chaîne brute ...?

Modifier:

Merci develerx, moutons volants et unutbu. Mais aucune des solutions ne semble m'aider. La raison en est qu'il existe d'autres caractères avec barre oblique inverse qui n'ont aucun effet dans python mais qui ont une signification dans latex.

Par exemple '\ lambda'. Toutes les méthodes suggérées produisent

\\lambda

qui ne passe pas par le traitement au latex - il doit rester comme\lambda.

Un autre montage:

Si je peux obtenir ce travail, je pense que je devrais avoir terminé. @Mark: Les trois méthodes donnent des réponses que je ne désire pas.

a='\nu + \lambda + \theta'; 
b=a.replace(r"\\",r"\\\\"); 
c='%r' %a; 
d=a.encode('string_escape');
print a

u + \lambda +   heta
print b

u + \lambda +   heta
print c
'\nu + \\lambda + \theta'
print d
\nu + \\lambda + \theta
39
Vijay Murthy

Les chaînes brutes de Python ne sont qu'un moyen de dire à l'interpréteur Python qu'il doit interpréter les barres obliques inverses comme des barres obliques littérales. Si vous lisez les chaînes entrées par l'utilisateur, elles ont déjà dépassé le point où elles auraient pu être En outre, les entrées utilisateur sont très probablement lues littéralement, c'est-à-dire "brutes".

Cela signifie que l'interprétation se produit ailleurs. Mais si vous savez que cela se produit, pourquoi ne pas échapper aux barres obliques inverses pour tout ce qui l'interprète?

s = s.replace("\\", "\\\\")

(Notez que vous ne pouvez pas faire r"\" as "une chaîne brute ne peut pas se terminer par une seule barre oblique inverse) , mais j'aurais pu utiliser r"\\" également pour le deuxième argument.)

Si cela ne fonctionne pas, votre entrée utilisateur est pour une raison obscure d'interprétation des barres obliques inverses, vous aurez donc besoin d'un moyen de lui dire d'arrêter cela.

41
flying sheep

Si vous souhaitez convertir une chaîne existante en chaîne brute, nous pouvons réaffecter cela comme ci-dessous

s1 = "welcome\tto\tPython"
raw_s1 = "%r"%s1
print(raw_s1)

Imprime

welcome\tto\tPython
15
prasad
a='\nu + \lambda + \theta'
d=a.encode('string_escape').replace('\\\\','\\')
print(d)
# \nu + \lambda + \theta

Cela montre qu'il y a une seule barre oblique inversée avant les n, l et t:

print(list(d))
# ['\\', 'n', 'u', ' ', '+', ' ', '\\', 'l', 'a', 'm', 'b', 'd', 'a', ' ', '+', ' ', '\\', 't', 'h', 'e', 't', 'a']

Il se passe quelque chose de génial avec votre interface graphique. Voici un exemple simple de saisie d'une entrée utilisateur via un Tkinter.Entry. Notez que le texte récupéré n'a qu'une seule barre oblique inverse avant n, l et t. Ainsi, aucun traitement supplémentaire ne devrait être nécessaire:

import Tkinter as tk

def callback():
    print(list(text.get()))

root = tk.Tk()
root.config()

b = tk.Button(root, text="get", width=10, command=callback)

text=tk.StringVar()

entry = tk.Entry(root,textvariable=text)
b.pack(padx=5, pady=5)
entry.pack(padx=5, pady=5)
root.mainloop()

Si vous tapez \nu + \lambda + \theta dans la zone de saisie, la console affichera (correctement):

['\\', 'n', 'u', ' ', '+', ' ', '\\', 'l', 'a', 'm', 'b', 'd', 'a', ' ', '+', ' ', '\\', 't', 'h', 'e', 't', 'a']

Si votre interface graphique ne renvoie pas de résultats similaires (comme votre message semble le suggérer), je vous recommande de chercher à résoudre le problème de l'interface graphique, plutôt que de contourner avec string_escape et chaîne replace.

5
unutbu

Lorsque vous lisez la chaîne à partir du contrôle GUI, il s'agit déjà d'une chaîne "brute". Si vous imprimez la chaîne, vous pourriez voir les barres obliques inversées doublées, mais c'est un artefact de la façon dont Python affiche les chaînes; en interne, il n'y a toujours qu'une seule barre oblique inverse.

>>> a='\nu + \lambda + \theta'
>>> a
'\nu + \\lambda + \theta'
>>> len(a)
20
>>> b=r'\nu + \lambda + \theta'
>>> b
'\\nu + \\lambda + \\theta'
>>> len(b)
22
>>> b[0]
'\\'
>>> print b
\nu + \lambda + \theta
3
Mark Ransom

J'ai passé beaucoup de temps à essayer différentes réponses sur Internet, et je soupçonne que les raisons pour lesquelles une chose fonctionne pour certaines personnes et pas pour d'autres sont dues à de très petites différences étranges dans l'application. Pour le contexte, je devais lire les noms de fichiers d'un fichier csv qui avait des caractères unicode étranges et/ou non mappables et les écrire dans un nouveau fichier csv. Pour ce que ça vaut, voici ce qui a fonctionné pour moi:

s = '\u00e7\u00a3\u0085\u00e5\u008d\u0095' # csv freaks if you try to write this
s = repr(s.encode('utf-8', 'ignore'))[2:-1]
2
Katherine