簡體   English   中英

在文件Python中進行條件搜索和替換

[英]Conditional Search and Replace in a file Python

需要條件搜索和替換時,我有一個超過10MB的大型文本文件。 如果“ a”之后的字符是“ r”或“ m”或“ n”或“ u”,我想用“ā”替換文件中“ a”的每個實例。

例如:輸入文件

Hamro sano ghar holata.

輸出文件

Hāmro sāno ghār holata.

編輯

謝謝大家,它似乎運作良好。 但這似乎不適用於非拉丁字符,例如印度腳本:拉丁字符的工作腳本:

#!/usr/bin/env python
#-*- coding: utf-8 -*-
import re
input = "Hamro sano ghar holata."
regex = re.compile(ur'a([rmnu])')
print regex.sub(ur'ā\1', input)

腳本1(用於梵文)不起作用

#!/usr/bin/env python
#-*- coding: utf-8 -*-
import re
input ="संगम"
regex = re.compile(ur'ं([कखगघ])')
print regex.sub(r'ङ्\1', input)

Script2(添加了unicode的東西)不起作用

#!/usr/bin/env python
#-*- coding: utf-8 -*-
import re
input =u"संगम"
regex = re.compile(ur'ं([कखगघ])', re.UNICODE)
print regex.sub(r'ङ्\1', input)

預期輸出:ं替換為ङ्,因為ग跟隨ं即सङ्गम

您需要在此處輸入一個簡單的正則表達式。 像這樣嗎

>>> import re
>>> input = "Hamro sano ghar holata."
>>> regex = re.compile(ur'a([rmnu])') # the part in parens is remembered
>>> print regex.sub(ur'ā\1', input) # replace by ā plus remembered part
Hāmro sāno ghār holata.

編輯:

一些背景,首先:

這是梵文一個艱巨的任務(देवनागरी),並不是因為編碼的,但因為結合的字形規則是非常復雜的(至少,由拉丁字母的標准)。 例如,我在Chrome上寫了這個答案,但仍然無法正確將Devanāgarī改成 “Devanāgarī”(它在錯誤的位置得到了'e'的變音符號-與dipthong'ai的用法相同')。

這些字形由文本渲染引擎組合的方式稱為“連字”,對於Devanāgarī ,從技術角度來看,它們非常復雜。 如果添加的संधि(saṃdhi -再次,Chrome的渲染變得代表放錯了地方的隨韻賓度 )推出的進一步巨大的並發症,那么你就可以看到你想在這里做可以迅速得到極其困難的。

綜上所述,如果您的問題僅限於這種簡單情況,那么我認為可以完全解決。

>>> import re
>>> inputString = u"संगम"
>>> regex = re.compile(ur'\u0902(?=[कखगघ])')
>>> print regex.sub(ur'ङ\u094d', inputString)
सङ्गम

在正則表達式中,為清楚起見,我用unicode轉義值替換了anusvāravirāma (印地語: halant )。 考慮到連字的工作方式,可能會遺漏某些情況,但是我已將示例轉換為使用先行方式,如@Kabie的示例(無論如何,這可能是一個更好的選擇),以盡可能地減輕這種情況。

re.sub(r'a(?=[rmnu])',r'ā',"Hamro sano ghar holata.")

對於較大的文本文件,應復制原始文件,替換字符,然后使用更新的行編寫新文件。 您一次只能讀取一個塊,而不是整個文件。 (盡管在一台現代計算機上,您可以一次吞噬整個10 MB。)

一種簡單的方法是將文件對象用作迭代器。 這一次從文件返回一行。

import re
pat = re.compile(ur'a([rmnu])') # pre-compile regex pattern for speed

f = open("corrected_file.txt", "wb")

for line in open("big_file_10mb.txt", "rb"):
    line = pat.sub(ur'ā\1', line)
    f.write(line)

f.close()

如果您想一次性處理整個文件,則可以使用.read()方法函數:

f = open("big_file_10mb.txt", "rb")
s = f.read()  # read entire file contents
f.close()
s = pat.sub(ur'ā\1', s)  # replace over entire file contents
f = open("corrected_file.txt", "wb")
f.write(s)  # write entire file contents
f.close(s)

除非您有充分的理由,否則請不要這樣做。 面向行的版本易於理解,並且與計算機上可用的內存相比,當文件較大時,效果更好。

Dive Into Python一書中有一章介紹了正則表達式:

http://diveintopython3.ep.io/regular-expressions.html

您要閱讀Unicode並替換Unicode字符。 您將需要弄清楚文件的本機編碼,將其讀入,轉換為Unicode,進行替換,然后以正確的編碼寫出。 或者,您可以使用特殊的“編解碼器”模塊; codecs.open()將為您提供一個自動為您轉換的文件對象。

這是Python的Unicode“操作方法”文檔:

http://docs.python.org/howto/unicode.html

因此,假設您要讀取的文本文件是使用UTF-8編碼的。 我認為這將為您工作:

import codecs
import re

pat = re.compile(ur'a([rmnu])') # pre-compile regex pattern for speed

f = codecs.open("corrected_file.txt", mode="wb", encoding="utf-8")

for line in codecs.open("big_file_10mb.txt", mode="rb", encoding="utf-8"):
    line = pat.sub(ur'ā\1', line)
    f.write(line)

f.close()

暫無
暫無

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

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