2016-12-21 21 views
1

NLPのトークン化タスクを処理し、Perl scriptからPython scriptにスクリプトを移植するのが目的です。PythonとPerlの正規表現のバックスラッシュとエスケープ文字

主な問題は、私たちがトークナイザのPythonのポートを実行したときに起こる誤ったバックスラッシュが付いています。何とか文字通りアンパサンドのエスケープ

>>> import re 
>>> from six import text_type 
>>> sent = text_type("this ain't funny") 
>>> escape_singquote = r"\'", r"\'" # escape the left quote for XML 
>>> contraction = r"n't", r" n't" # pad a space on the left when "n't" pattern is seen 
>>> text = sent 
>>> for regexp, substitution in [contraction, escape_singquote]: 
...  text = re.sub(regexp, substitution, text) 
...  print text 
... 
this ai n't funny 
this ai n\'t funny 

Pythonの

に正規表現を移植

my($text) = @_; # Reading a text from stdin 

$text =~ s=n't = n't =g; # Puts a space before the "n't" substring to tokenize english contractions like "don't" -> "do n't". 

$text =~ s/\'/\'/g; # Escape the single quote so that it suits XML. 

としてこれを追加しました:

Perlでは、我々は、単一引用符とのようなアンパサンドをエスケープする必要がある可能性がありリテラルバックスラッシュ=(

これを解決するには、私はできる:

>>> escape_singquote = r"\'", r"'" # escape the left quote for XML 
>>> text = sent 
>>> for regexp, substitution in [contraction, escape_singquote]: 
...  text = re.sub(regexp, substitution, text) 
...  print text 
... 
this ai n't funny 
this ai n't funny 

しかし、一見Pythonで単一引用符をエスケープせずに、私たちも望ましい結果を得る:

>>> import re 
>>> from six import text_type 
>>> sent = text_type("this ain't funny") 
>>> escape_singquote = r"\'", r"\'" # escape the left quote for XML 
>>> contraction = r"n't", r" n't" # pad a space on the left when "n't" pattern is seen 
>>> escape_singquote = r"'", r"'" # escape the left quote for XML 
>>> text = sent 
>>> for regexp, substitution in [contraction, escape_singquote]: 
...  text = re.sub(regexp, substitution, text) 
...  print text 
... 
this ai n't funny 
this ai n't funny 

は、今では、上記の文脈を考えると...

不可解ですので、質問がためです文字はPythonでエスケープする必要があり、Perlではどの文字を使用しますか? PerlとPythonの正規表現はそれと同等の権利はありませんか? PerlやPythonの両方で

+0

すべての生の文字列を使用しています。バックスラッシュはリテラルです。 – TigerhawkT3

+1

これを確認してください:http://stackoverflow.com/questions/7063420/perl-compatible-regular-expression-pcre-in-python – MYGz

+0

Perlバージョンでもバックスラッシュは必要ありません。 – Borodin

答えて

3

、あなたは文字クラスの外に文字通りそれらを一致させたい場合は、次の正規表現のメタ文字をエスケープする必要があります。

{}[]()^$.|*+?\ 

文字クラスの中で、あなたはエスケープする必要がありメタ文字これらの規則に従って:

 Perl       Python 
------------------------------------------------------------- 
- unless at beginning or end unless at beginning or end 
] always      unless at beginning 
\ always      always 
^ only if at beginning   only if at beginning 
$ always      never 

なお、単一引用符でもない'もアンパサンド文字クラスの内側であろうとなかろうと、10はエスケープされなければならない。あなたはメタ文字ではない句読点文字をエスケープするためにそれを使用する場合

しかし、PerlとPythonの両方がバックスラッシュを無視します(例えば\'は、正規表現の内側'に相当します)。

あなたがPythonの raw stringsに巻きトリップなっているようだ

'r'または'R'接頭辞が存在する場合、バックスラッシュの後の文字は変更せずに、文字列に含まれ、すべてのバックスラッシュがあるさ文字列の中に残っています。

r"\'"r'\''が文字列\'(等リテラルバックスラッシュ、リテラルアンパサンド)であるが、文字列\'(リテラルバックスラッシュ、リテラル単一引用符)です。

ので、この:

re.sub(r"\'", r'\'', text) 

はリテラルテキスト\'を持つすべての単一引用符を置き換えます。

$text =~ s/'/'/g; 

をそして、あなたのPythonの置換が良く書かれている:すべて一緒にそれを置く


は、あなたのPerlの置換が良く書かれている


  1. のPython 2

    re.sub(r"'", r''', text) 
    
    、 Python 3、および現在のバージョンのPerlはnon-eを扱います数量化の一部でない場合は、中括弧をリテラル中括弧で囲みます。しかし、これはPerlの将来のバージョンでは構文エラーとなり、最近のPerlでは警告が出ます。

  2. perlretut,perlre、およびのPythonドキュメントを参照してください。

+1

補足として、HTML/XMLエンティティをエンコードしようとしている場合は、一連の正規表現を書く代わりにモジュールを使用する必要があります。 Perlには他にも[HTML :: Entities](https://metacpan.org/pod/HTML::Entities)があります。 Python 2をすばやく検索すると[cgi.escape](https://docs.python.org/2/library/cgi.html#cgi.escape)が表示されます。 – ThisSuitIsBlackNot

+0

私はPythonのXMLエスケープを使うのも良い考えだと思います!しかし、このタスクの場合はあまりにも悪いので、後で下流のタスクのために保存することをお勧めします。 – alvas

関連する問題