簡體   English   中英

Python替換除Apostrophes之外的單引號

[英]Python Replace Single Quotes Except Apostrophes

我正在對單詞列表執行以下操作。 我從Project Gutenberg文本文件中讀取行,在空格上划分每一行,執行一般標點符號替換,然后在其自己的行上打印每個單詞和標點符號以便稍后進行進一步處理。 我不確定如何用標簽替換每個單引號或者除了所有撇號。 我目前的方法是使用編譯的正則表達式:

apo = re.compile("[A-Za-z]'[A-Za-z]")

並執行以下操作:

if "'" in word and !apo.search(word):
    word = word.replace("'","\n<singlequote>")

但是這忽略了在帶有撇號的單詞周圍使用單引號的情況。 它也沒有向我表明單引號是否與單詞結尾的單詞的開頭相鄰。

輸入示例:

don't
'George
ma'am
end.'
didn't.'
'Won't

示例輸出(處理和打印到文件后):

don't
<opensingle>
George
ma'am
end
<period>
<closesingle>
didn't
<period>
<closesingle>
<opensingle>
Won't

關於這個任務我還有一個問題:因為<opensingle> vs <closesingle>的區別似乎相當困難,所以更明智地執行替換

word = word.replace('.','\n<period>')
word = word.replace(',','\n<comma>')

在進行更換操作之后

我建議在這里工作:使用nltk或其他NLP工具包代替。

Tokenize這樣的單詞

import nltk
sentence = """At eight o'clock on Thursday morning
Arthur didn't feel very good."""
tokens = nltk.word_tokenize(sentence)

你可能不喜歡像沒有分開的收縮這樣的事實。 實際上,這是預期的行為。 問題401

但是,TweetTokenizer可以提供幫助:

from nltk.tokenize import tknzr = TweetTokenizer()
tknzr.tokenize("The code didn't work!")

如果它涉及更多,RegexpTokenizer可能會有所幫助:

from nltk.tokenize import RegexpTokenizer
s = "Good muffins cost $3.88\nin New York.  Please don't buy me\njust one of them."
tokenizer = RegexpTokenizer('\w+|\$[\d\.]+|\S+')
tokenizer.tokenize(s)

然后,正確地注釋標記化的單詞應該更容易。

進一步參考:

你真正需要正確替換的開始和結束'正則表達式 要匹配它們,您應該使用:

  • ^'開始'opensingle ),
  • '$ for ending 'closesingle )。

不幸的是, replace方法不支持正則表達式,所以你應該使用re.sub

下面是一個示例程序,打印您想要的輸出(在Python 3中 ):

import re
str = "don't 'George ma'am end.' didn't.' 'Won't"
words = str.split(" ")
for word in words:
    word = re.sub(r"^'", '<opensingle>\n', word)
    word = re.sub(r"'$", '\n<closesingle>', word)
    word = word.replace('.', '\n<period>')
    word = word.replace(',', '\n<comma>')
    print(word)

我認為這可以從先行或后觀引用中受益。 python引用是https://docs.python.org/3/library/re.html ,我經常引用的一個通用正則表達式站點是https://www.regular-expressions.info/lookaround.html

你的數據:

words = ["don't",
         "'George",
         "ma'am",
         "end.'",
         "didn't.'",
         "'Won't",]

現在我將定義一個帶有正則表達式及其替換的元組。

In [230]: apo = (
    (re.compile("(?<=[A-Za-z])'(?=[A-Za-z])"), "<apostrophe>",),
    (re.compile("(?<![A-Za-z])'(?=[A-Za-z])"), "<opensingle>",),
    (re.compile("(?<=[.A-Za-z])'(?![A-Za-z])"), "<closesingle>", ),
    (re.compile("(?<=[A-Za-z])\\.(?![A-Za-z])"), "<period>",),
)
     ...:      ...:      ...:      ...:      ...:      ...: 
In [231]: words = ["don't",
         "'George",
         "ma'am",
         "end.'",
         "didn't.'",
         "'Won't",]
     ...:      ...:      ...:      ...:      ...:      ...: 
In [232]: reduce(lambda w2,x: [ x[0].sub(x[1], w) for w in w2], apo, words)
Out[232]: 
['don<apostrophe>t',
 '<opensingle>George',
 'ma<apostrophe>am',
 'end<period><closesingle>',
 'didn<apostrophe>t<period><closesingle>',
 '<opensingle>Won<apostrophe>t']

以下是正則表達式的內容:

  1. (?<=[A-Za-z])是一個lookbehind ,意思是只有匹配(但不消耗 )前面的字符是一個字母。
  2. 如果以下字符是字母,則(?=[A-Za-z])前瞻 (仍然沒有消耗)。
  3. (?<![A-Za-z])是一個負面的后視 ,意思是如果它前面有一個字母,那么它將不匹配。
  4. (?![A-Za-z])是一個負向前瞻

請注意,我添加了一個. 檢查<closesingle> ,並且apo的順序很重要,因為您可能正在替換. <period> ...

這是在單個單詞上運行,但也應該與句子一起使用。

In [233]: onelong = """
don't
'George
ma'am
end.'
didn't.'
'Won't
"""
     ...:      ...:      ...:      ...:      ...:      ...:      ...: 
In [235]: print(
    reduce(lambda sentence,x: x[0].sub(x[1], sentence), apo, onelong)
)

     ...:      ...: 
don<apostrophe>t
<opensingle>George
ma<apostrophe>am
end<period><closesingle>
didn<apostrophe>t<period><closesingle>
<opensingle>Won<apostrophe>t

(使用reduce是為了方便在單詞/字符串上應用正則表達式的.sub ,然后將該輸出保存到下一個正則表達式的.sub等中)

暫無
暫無

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

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