簡體   English   中英

Python正則表達式:如何從字符串中刪除所有標點符號,但將它們保留在數字之間?

[英]python regular expression : how to remove all punctuation characters from a string but keep those between numbers?

我正在從事中國NLP項目。 我需要刪除所有標點符號,數字之間的那些字符除外,並且僅保留漢字(\\ u4e00- \\ u9fff),字母數字字符(0-9a-zA-Z)。例如,應保留12-34中的連字符123之后的等號應被刪除。

這是我的python腳本。

import re
s = "中國,中,。》%國foo中¥國bar@中123=國%中國12-34中國"
res = re.sub(u'(?<=[^0-9])[^\u4e00-\u9fff0-9a-zA-Z]+(?=[^0-9])','',s)
print(res)

預期的輸出應該是

中國中國foo中國bar中123國中國12-34中國

但結果是

中國中國foo中國bar中123=國中國12-34中國

我不知道為什么輸出中會有一個額外的等號?

您的正則表達式將首先針對[^\一-\鿿0-9a-zA-Z]+檢查"=" 這將成功。 然后它將檢查向后查找和向前查找,這兩者都必須失敗。 即:如果其中之一成功,則保留角色。 這意味着你的代碼實際上保持這對任何一方的數字任何非字母數字字符,非中國字。

您可以嘗試以下正則表達式:

u'([\u4e00-\u9fff0-9a-zA-Z]|(?<=[0-9])[^\u4e00-\u9fff0-9a-zA-Z]+(?=[0-9]))'

您可以這樣使用它:

import re
s = "中國,中,。》%國foo中¥國bar@中123=國%中國12-34中國"
res = re.findall(u'([\u4e00-\u9fff0-9a-zA-Z]|(?<=[0-9])[^\u4e00-\u9fff0-9a-zA-Z]+(?=[0-9]))',s)
print(res.join(''))

我建議在數字之間匹配和捕獲這些字符(以在以后的輸出中恢復它們),並僅在其他上下文中匹配它們。

在Python 2中,它看起來像

import re
s = u"中國,中,。》%國foo中¥國bar@中123=國%中國12-34中國"
pat_block = u'[^\u4e00-\u9fff0-9a-zA-Z]+';
pattern = u'([0-9]+{0}[0-9]+)|{0}'.format(pat_block)
res = re.sub(pattern, lambda x: x.group(1) if x.group(1) else u"" ,s)
print(res.encode("utf8")) # => 中國中國foo中國bar中123國中國12-34中國

參見Python演示

如果需要將這些符號保留在任何Unicode數字內,則需要用\\d替換[0-9] ,並將re.UNICODE標志傳遞給正則表達式。

正則表達式看起來像

([0-9]+[^\u4e00-\u9fff0-9a-zA-Z]+[0-9]+)|[^\u4e00-\u9fff0-9a-zA-Z]+

它將像這樣工作:

  • ([0-9]+[^\一-\鿿0-9a-zA-Z]+[0-9]+) -組1捕獲
    • [0-9]+ -1+個數字
    • [^\一-\鿿0-9a-zA-Z]+ 1-除指定范圍內定義的字符以外的1個字符
    • [0-9]+ -1+個數字
  • | - 要么
  • [^\一-\鿿0-9a-zA-Z]+ 1-除指定范圍內定義的字符以外的1個字符

在Python 2.x中,當re.sub的組不匹配時,對它的后向引用為None ,這就是為什么需要lambda表達式來檢查組1是否首先匹配的原因。

暫無
暫無

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

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