あなたの唯一の本当の問題は、バックスラッシュがトリッキーであるということです。文字列では、円記号は特別に扱われる場合があります。たとえば\t
、タブに変わります。文字列は特別ではないので\+
、文字列は実際にはあなたが期待したものでした。したがって、正規表現コンパイラはそれを調べ\+
、正規表現では単なる+
文字になります。通常、+
は特別な意味(「前のパターンの1つ以上のインスタンス」)を持ち、バックスラッシュはそれをエスケープします。
解決策は、バックスラッシュを2倍にすることです。これにより、1つのバックスラッシュに一致するパターンが作成されます。
パターンをに入れてr''
、Pythonがバックスラッシュだけを残す「生の文字列」にします。そうしないと、Pythonの文字列パーサーが2つの円記号を1つの円記号に変換します。\t
タブに変わるのと同じよう\\
に、単一の円記号に変わります。したがって、生の文字列を使用して、正規表現コンパイラに表示させたいものを正確に配置します。
また、より適切なパターンは、バックスラッシュ、x、16進文字に一致する文字クラスの1つ以上のインスタンスです。これにパターンを書き直しました。
import re
s = r'+\x01+'
escape_char = re.compile(r'\\x[0123456789abcdef]+')
s = re.sub(escape_char, " ", s)
生の文字列を使用する代わりに、通常の文字列を使用して、円記号に十分注意することができます。この場合、4つの円記号を付ける必要があります。文字列パーサーは、二重化された各バックスラッシュを1つのバックスラッシュに変換し、正規表現コンパイラーに2つのバックスラッシュを認識させます。生の文字列を使用する方が簡単です。
また、元のパターンでは、0個以上の16進数が削除されます。私のパターンは1つ以上を削除します。しかし、16進数は常に正確に2桁になる可能性が高いと思います。あるいは、Unicodeでは4桁になる可能性があります。いくつあるかを把握し、これを確実にするパターンを設定する必要があります。2、3、または4桁の16進数に一致するパターンは次のとおりです。
escape_char = re.compile(r'\\x[0123456789abcdef]{2,4}')
そして、これは正確に2つまたは正確に4つに一致するものです。2つの選択肢を作成するには、垂直バーを使用する必要があり、括弧付きのグループを作成する必要があります。ここでは、 (文字通りの単語ではなく、パターンを意味する)の(?:pattern)
代わりに、一致しないグループを使用しています。(pattern)
pattern
pattern
escape_char = re.compile(r'\\x(?:[0123456789abcdef]{2,2}|[0123456789abcdef]{4,4})')
これがサンプルコードです。弾丸シーケンスの直後に文字が続き1
、このパターンはそれをそのままにします。
import re
s = r'+\x011+'
pat = re.compile(r'\\x(?:[0123456789abcdef]{2,2}|[0123456789abcdef]{4,4})')
s = pat.sub("@", s)
print("Result: '%s'" % s)
これは印刷します:Result: '+@1+'
注:これはすべて、バックスラッシュ文字とそれに続く16進文字を実際に一致させようとしていることを前提としています。「印刷可能な」文字である場合とそうでない場合がある文字バイト値を実際に一致させようとしている場合は、これの代わりに@nneonneoによる回答を使用してください。