簡體   English   中英

Python與Perl正則表達式中的反斜杠和轉義字符

[英]Backslashes and escaping chars in Python vs Perl regexes

目標是處理NLP中的標記化任務,並將腳本從Perl腳本移植到此Python腳本

主要問題與錯誤的反斜杠有關,當我們運行令牌生成器的Python端口時,就會發生反斜杠。

在Perl中,我們可能需要這樣來轉義單引號和“&”號:

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.

從字面上將正則表達式移植到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

轉義符號的轉義以某種方式將其添加為反斜杠=(

為了解決這個問題,我可以這樣做:

>>> 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中的Regex不是那么等效嗎?

在Perl和Python中,如果要在字符類1之外按字面意義匹配以下正則表達式元字符,則必須轉義它們:

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

在字符類內部,必須根據以下規則2來轉義元字符:

     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

請注意,無論是單引號'也不符號&必須進行轉義,里面是否或字符類的外部。

但是,如果你用它來逃脫一個標點符號是不是元字符都Perl和Python會忽略反斜杠(例如\\'等同於'正則表達式中)。


您似乎被Python的原始字符串絆倒了:

如果存在'r''R'前綴,則字符串中包含反斜杠后面的字符而不會更改,並且所有反斜杠都保留在字符串中。

r"\\'"是字符串\\' (字面反斜杠,字面單引號),而r'\\'' 是字符串\\' (文字反斜杠,文字&符等)。

所以這:

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

用文字文本\\'替換所有單引號\\'


綜上所述,您的Perl替代詞寫得更好:

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

而且您的Python替代文字寫得更好:

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

  1. 如果Python 2,Python 3和當前版本的Perl不屬於量詞,則它們會將未轉義的花括號視為文字花括號。 但是,這將在Perl的將來版本中出現語法錯誤,並且Perl的最新版本會發出警告。

  2. 有關re模塊 ,請參見perlretutperlre和Python文檔。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM