欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python?RawString與open文件的newline換行符遇坑解決

 更新時(shí)間:2022年10月14日 11:37:20   作者:HullQin  
這篇文章主要為大家介紹了Python?RawString與open文件的newline換行符遇坑解決示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

背景

一次工作中,我需要完成某個(gè)文件的字符串替換。

需求是這樣的:文件A有個(gè)占位符,需要利用Python3,把占位符替換成文件B的內(nèi)容。文件都不大,可以一次性讀到內(nèi)存處理。

我想,這不是簡(jiǎn)單的open read replace write就搞定了嘛?

結(jié)果,還真有點(diǎn)麻煩!

思路

  • 全量讀取文件A,保存到變量templace
  • 全量讀取文件B,保存到變量text
  • 利用python的re.sub實(shí)現(xiàn)正則替換,保存到新變量result
  • 把變量result內(nèi)容寫入文件A
with open('A', encoding='utf8') as f:
  template = f.read()
with open('B', encoding='utf8') as f:
  text = f.read()
result = re.sub(r'占位標(biāo)識(shí)符', text, template, 1)
with open('A', 'w', encoding='utf8') as f:
  f.write(result)

遇到的問(wèn)題

文件B內(nèi)有換行符,也有字符串\n,按上文的方式處理后,所有的字符串\n都變成了換行符!

舉個(gè)例子,template是我是:{}(其中{}就是占位符),text是下面的文本:

哈哈
哈哈\n哈哈

替換后,如下圖所示:

可以看到,當(dāng)我打印re.sub結(jié)果時(shí),所有的\n都變成了換行符,字符串\n消失了!

這的確令人煩躁,本來(lái)五分鐘可以搞定,結(jié)果要花多余的時(shí)間處理這個(gè)問(wèn)題。如果你學(xué)會(huì)了本文,以后都不用再去費(fèi)腦筋了~

思考過(guò)程

一開(kāi)始遇到這個(gè)問(wèn)題,是在寫入文件后發(fā)現(xiàn)的,所以并沒(méi)定位的這么準(zhǔn)確,當(dāng)時(shí)跟換行符相關(guān)的,我懷疑了以下方面:

  • 字符串定義沒(méi)有使用 Raw String(例如r'xxx'這種方式)。
  • 正則替換出了問(wèn)題。
  • 寫入文件時(shí),newline參數(shù)導(dǎo)致。

如果我們能把這3個(gè)問(wèn)題全都弄清楚,以后定位就非??炝耍?/p>

Raw String

Python中,如果字符串常量的定義前加了個(gè)r,就表示 Raw String 原始字符串。

Raw String 特點(diǎn)在于,字符串常量里的\將不具有轉(zhuǎn)義作用,它僅僅代表它自己。

例如,你定義個(gè)普通字符串"\n",這個(gè)字符串長(zhǎng)度其實(shí)是1,它只包含了1個(gè)換行符,對(duì)應(yīng)的 ASCII 是10。

如果你定義了原始字符串"\n",這個(gè)字符串長(zhǎng)度就是2,它包含了字符\和字符n。

如果字符串沒(méi)轉(zhuǎn)義字符,那么 Raw String 跟普通 String 完全一致

轉(zhuǎn)義字符有這些:

也就是說(shuō)r'\haha''\haha'是完全一致的,因?yàn)?code>\h不是轉(zhuǎn)義字符,所以這種情況下,沒(méi)必要加r。

誤區(qū):注意單個(gè)字符的引號(hào)問(wèn)題

有一個(gè)令人疑惑的點(diǎn):理論上講,r'\'應(yīng)該就是'\\',但是當(dāng)你使用r'\'時(shí),Python會(huì)報(bào)錯(cuò)。

這是因?yàn)镻ython在編譯時(shí),讀取字符串時(shí),如果字符串以單引號(hào)開(kāi)頭,遇到\'后,不論你是不是Raw String,都會(huì)繼續(xù)認(rèn)為是字符串,不會(huì)把'當(dāng)作結(jié)束符。估計(jì)是一個(gè)歷史遺留問(wèn)題。我們只能接受現(xiàn)實(shí)。

如何證明呢?你給字符后面加個(gè)空格,發(fā)現(xiàn)它們是相等的:r'\ ''\\ '。但是單獨(dú)的字符r'\'就報(bào)錯(cuò)了。

但是這種情況只有r'\'r"\"才會(huì)發(fā)生,如果字符串長(zhǎng)度為2,是沒(méi)問(wèn)題的,例如r"\\"可以被合法定義。

啟發(fā)

定義字符串時(shí),如果你是這么定義:"哈哈\n哈哈",那么這個(gè)字符串長(zhǎng)度是5,包含了1個(gè)換行符。

如果你是這么定義:r"哈哈\n哈哈",那么這個(gè)字符串長(zhǎng)度是6,不包含換行符,包含字符\n。

同樣,當(dāng)你寫入文件時(shí),如果是f.write('\n'),就表明寫入了換行符,但如果是f.write(r'\n'),就表明寫入了字符串"\n"。

正則替換的問(wèn)題

這是導(dǎo)致本文問(wèn)題的根本原因。使用re.sub時(shí),所有的字符串r"\n"都被當(dāng)作了換行符。

怎么辦呢?

只要我們替換前,把原始文件對(duì)應(yīng)的字符串的r"\n"都改為r"\\n",手動(dòng)多加了一次轉(zhuǎn)義符,那么re.sub時(shí),就不會(huì)把r"\n"當(dāng)作一個(gè)整體改成換行符了,反而會(huì)把r"\\"當(dāng)作一個(gè)整體,替換為字符\。這樣r"\n"字符串就保留下來(lái)了!當(dāng)然,其它轉(zhuǎn)義字符,也統(tǒng)統(tǒng)保留下來(lái)了。這就是正確的解法了。

open 文件的 newline 參數(shù)

with open(filename, 'r', newline=None) as f:
  f.read()

這個(gè)主要是因?yàn)椴煌僮飨到y(tǒng)的換行符不同,所以有了這個(gè)參數(shù)。Windows 是 CRLF 即 \r\n,Unix 是 LF 即\n,舊版 Macintosh 是 CR 即\r

通常情況下,我們不需要加這個(gè)參數(shù),Python 會(huì)自動(dòng)為我們做這些事情:

  • 讀取文件時(shí),自動(dòng)把文本中的各種換行符統(tǒng)一轉(zhuǎn)換為"\n"。
  • 寫入文件時(shí),根據(jù)當(dāng)前的操作系統(tǒng),自動(dòng)把"\n"轉(zhuǎn)換為對(duì)應(yīng)的換行符,通過(guò)os.linesep可以查看當(dāng)前操作系統(tǒng)換行符。

當(dāng)然,你也可以主動(dòng)設(shè)置 newline 參數(shù):

  • 讀取文件時(shí),如果 newline 是空字符串'',則Python不會(huì)做任何自動(dòng)轉(zhuǎn)換,讀到什么就是什么。
  • 讀取文件時(shí),如果 newline 是非空字符串,則Python會(huì)把換行符轉(zhuǎn)化為這個(gè)非空字符串,例如你可以指定為'\r''\r\n'或其它。
  • 寫入文件時(shí),如果 newline 是空字符串'',則Python不會(huì)做任何自動(dòng)轉(zhuǎn)換,現(xiàn)在換行符是什么,就寫入什么。
  • 寫入文件時(shí),如果 newline 是非空字符串,則Python會(huì)把\n轉(zhuǎn)化為這個(gè)非空字符串,例如你可以指定為'\r''\r\n'或其它。

注意,newline 參數(shù)只對(duì)文本文件有效,如果是二進(jìn)制讀寫,newline 是無(wú)用的。

其實(shí),大部分時(shí)候我們無(wú)需關(guān)注這個(gè) newline 參數(shù)。

以上就是Python RawString與open文件的newline換行符遇坑解決的詳細(xì)內(nèi)容,更多關(guān)于Python RawString open文件 newline換行符的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • python 通過(guò)pip freeze、dowload打離線包及自動(dòng)安裝的過(guò)程詳解(適用于保密的離線環(huán)境

    python 通過(guò)pip freeze、dowload打離線包及自動(dòng)安裝的過(guò)程詳解(適用于保密的離線環(huán)境

    這篇文章主要介紹了python 通過(guò)pip freeze、dowload打離線包及自動(dòng)安裝【適用于保密的離線環(huán)境】,本文通圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • VSCode配置python環(huán)境及中文問(wèn)題解決方法

    VSCode配置python環(huán)境及中文問(wèn)題解決方法

    這篇文章主要介紹了VSCode配置python環(huán)境及中文問(wèn)題,print打印中文亂碼如何解決這個(gè)問(wèn)題呢,本文給大家?guī)?lái)兩種方法幫助大家解決這個(gè)問(wèn)題,需要的朋友可以參考下
    2022-02-02
  • python鏈表類中獲取元素實(shí)例方法

    python鏈表類中獲取元素實(shí)例方法

    在本篇文章里小編給大家整理的是一篇關(guān)于python鏈表類中獲取元素實(shí)例方法,有興趣的朋友們可以學(xué)習(xí)下。
    2021-02-02
  • 教女朋友學(xué)Python(一)運(yùn)行環(huán)境搭建

    教女朋友學(xué)Python(一)運(yùn)行環(huán)境搭建

    這篇文章主要介紹了教女朋友學(xué)Python(一)運(yùn)行環(huán)境搭建,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-11-11
  • tkinter動(dòng)態(tài)顯示時(shí)間的兩種實(shí)現(xiàn)方法

    tkinter動(dòng)態(tài)顯示時(shí)間的兩種實(shí)現(xiàn)方法

    這篇文章主要介紹了tkinter動(dòng)態(tài)顯示時(shí)間的兩種實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • 雙向RNN:bidirectional_dynamic_rnn()函數(shù)的使用詳解

    雙向RNN:bidirectional_dynamic_rnn()函數(shù)的使用詳解

    今天小編就為大家分享一篇雙向RNN:bidirectional_dynamic_rnn()函數(shù)的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-01-01
  • pyqt5中動(dòng)畫的使用詳解

    pyqt5中動(dòng)畫的使用詳解

    這篇文章主要介紹了pyqt5中動(dòng)畫的使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • 用python讀取xlsx文件

    用python讀取xlsx文件

    這篇文章主要介紹了用python讀取xlsx文件的方法,幫助大家更好的利用python處理excel文件,感興趣的朋友可以了解下
    2020-12-12
  • 詳談Python高階函數(shù)與函數(shù)裝飾器(推薦)

    詳談Python高階函數(shù)與函數(shù)裝飾器(推薦)

    下面小編就為大家?guī)?lái)一篇詳談Python高階函數(shù)與函數(shù)裝飾器(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • Python中偏函數(shù)用法示例

    Python中偏函數(shù)用法示例

    這篇文章主要介紹了Python中偏函數(shù)用法,結(jié)合實(shí)例形式分析了Python基于functools模塊創(chuàng)建和使用偏函數(shù)的相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下
    2018-06-06

最新評(píng)論