自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何正確保留大括號(hào)?

開發(fā) 前端
自從Python 3.6開始,引入了f表達(dá)式(f-string),這使得Python在填充字符串時(shí)可以進(jìn)行一些簡(jiǎn)單的計(jì)算。并且f表達(dá)式的運(yùn)算速度是字符串.format方法的很多倍。

[[377067]]

自從Python 3.6開始,引入了f表達(dá)式(f-string),這使得Python在填充字符串時(shí)可以進(jìn)行一些簡(jiǎn)單的計(jì)算。并且f表達(dá)式的運(yùn)算速度是字符串.format方法的很多倍。

無論是f表達(dá)式還是字符串的.format方法,我們都可以使用大括號(hào)作為占位符,來填充數(shù)據(jù)。例如:

  1. >>> name = 'kingname' 
  2. >>> print(f'我的名字是:{name}'
  3. 我的名字是:kingname 
  4. >>> print(f'1+1的結(jié)果為:{1 + 1}'
  5. 1+1的結(jié)果為:2 
  6. >>> salary = 999999 
  7. >>> print('我的月薪是:{salary}'.format(salary=salary)) 
  8. 我的月薪是:999999 

但現(xiàn)在問題來了,如果我希望在使用f表達(dá)式或者.format方法填充內(nèi)容的同時(shí),又能保留大括號(hào)應(yīng)該怎么辦呢?

舉個(gè)例子,在寫爬蟲的時(shí)候,我需要使用正則表達(dá)式從當(dāng)前URL中提取當(dāng)前的頁數(shù):page=\d{0,3}。但是,對(duì)于不同的網(wǎng)站,表示頁數(shù)的這個(gè)參數(shù)名可能是不一樣的,有些是page=xxx,有些是Pag=xxx,有些是pageNo=xxx,有些是p=xxx。所以我想動(dòng)態(tài)生成這個(gè)正則表達(dá)式。

如果我們直接使用f表達(dá)式或者.format方法,就會(huì)報(bào)錯(cuò):

  1. >>> page_name = 'page' 
  2. >>> page_regex_template = '{page_name}=\d{0,3}' 
  3. >>> print(page_regex_template.format(page_name=page_name)) 
  4. Traceback (most recent call last): 
  5.   File "<stdin>", line 1, in <module> 
  6. KeyError: '0,3' 

為了能夠正常生成正則表達(dá)式,可能有人會(huì)想到使用古老的%s占位符:

  1. >>> page_name = 'page' 
  2. >>> page_regex_template = '%s=\d{0,3}' 
  3. >>> print(page_regex_template % page_name) 
  4. page=\d{0,3} 

雖然確實(shí)可行,但是混用兩種填充字符串的方法,代碼會(huì)變得不好維護(hù),而且%s這種占位符填充速度也非常慢。

實(shí)際上,在Python的f表達(dá)式和.format方法中,如果你需要保留大括號(hào),那么只需要寫成大括號(hào)套大括號(hào)的形式就行了:

  1. >>> page_name = 'page' 
  2. >>> page_regex_template = '{page_name}=\d{{0,3}}' 
  3. >>> print(page_regex_template.format(page_name=page_name)) 
  4. page=\d{0,3} 

大括號(hào)里面的第一層大括號(hào)會(huì)自動(dòng)失效,變成普通的字符。但如果是大括號(hào)套大括號(hào)套大括號(hào),那么最里面的一對(duì)大括號(hào)會(huì)繼續(xù)生效充當(dāng)占位符,例如:

  1. >>> page_name = 'page' 
  2. >>> page_range = '0,5' 
  3. >>> page_regex_template = '{page_name}=\d{{{page_range}}}' 
  4. >>> print(page_regex_template.format(page_name=page_name, page_range=page_range)) 
  5. page=\d{0,5} 

總結(jié)起來就是,如果從外向內(nèi)數(shù),如果最外層大括號(hào)稱為第1層,那么,第奇數(shù)層的大括號(hào)用來填充數(shù)據(jù),第偶數(shù)層的大括號(hào)就是普通的字符。因此,如果不考慮代碼可讀性,如果我們需要最終生成的字符串本身就是嵌套大括號(hào)的形式,我們還可以進(jìn)一步寫成:

  1. >>> ugly_string = '2層嵌套大括號(hào):{{{{{variable}}}}}' 
  2. >>> print(ugly_string.format(variable=variable)) 
  3. 2層嵌套大括號(hào):{{name}} 
  4. >>> ugly_string = '3層嵌套大括號(hào):{{{{{{{variable}}}}}}}' 
  5. >>> print(ugly_string.format(variable=variable)) 
  6. 3層嵌套大括號(hào):{{{name}}} 

假設(shè)我們希望最終輸出的字符串里面,保留n層大括號(hào),那么在代碼里面,我們需要寫2n + 1層大括號(hào)。大家也看出來了,如果你要這樣寫,數(shù)大括號(hào)的個(gè)數(shù)都要把你的眼鏡數(shù)瞎。所以,在實(shí)際開發(fā)中,大括號(hào)的層數(shù)絕對(duì)不要超過2層。

以下內(nèi)容供學(xué)有余力的同學(xué)閱讀。

上面講到的方法,適用于大括號(hào)成對(duì)出現(xiàn)的情況,如果大括號(hào)只有半邊,例如有些網(wǎng)站的正文信息是以JSON格式寫在源代碼里面的,于是我們可以使用正則表達(dá)式提取出包含正文的JSON然后進(jìn)一步處理,一般來說,正則表達(dá)式可能是這樣的:content=(\{);。不過,有的網(wǎng)站用的單詞是content,有的網(wǎng)站用的是detail,所以這個(gè)地方需要填充,如果我們像往常那樣寫,那么還是會(huì)報(bào)錯(cuò),例如:

  1. >>> content_name = 'detail' 
  2. >>> content_json_template = '{content_name}=({\{})$' 
  3. >>> print(content_json_template.format(content_name=content_name)) 
  4. Traceback (most recent call last): 
  5.   File "<stdin>", line 1, in <module> 
  6. ValueError: unexpected '{' in field name 

套一層不行,那我們看看套兩層如何:

  1. >>> content_name = 'detail' 
  2. >>> content_json_template = '{content_name}=({{\{}})$' 
  3. >>> print(content_json_template.format(content_name=content_name)) 
  4. Traceback (most recent call last): 
  5.   File "<stdin>", line 1, in <module> 
  6. IndexError: Replacement index 0 out of range for positional args tuple 

套兩層還是錯(cuò)。

如果字符串不含反斜杠,我們可以使用f表達(dá)式配合引號(hào)包住半邊大括號(hào)來實(shí)現(xiàn),例如:

  1. >>> name = 'kingname' 
  2. >>> print(f'我的名字是:{name},我的參數(shù)是:{"{"}'
  3. 我的名字是:kingname,我的參數(shù)是:{ 

但問題是,f表達(dá)式里面是不允許出現(xiàn)反斜杠的,否則會(huì)報(bào)錯(cuò):

  1. >>> content_name = 'detail' 
  2. >>> content_regex = f'{content_name}=({\"{"})$' 
  3.   File "<stdin>", line 1 
  4. SyntaxError: f-string expression part cannot include a backslash 

而.format方法支持反斜杠,但它又不支持引號(hào)包住單邊大括號(hào)的寫法:

  1. >>> name = 'kingname' 
  2. >>> print('我的名字是:{name},我的參數(shù)是:{"{"}'.format(name=name)) 
  3. Traceback (most recent call last): 
  4.   File "<stdin>", line 1, in <module> 
  5. ValueError: unexpected '{' in field name 

遇到這種情況,我們應(yīng)該怎么解決呢?只要把思路放開,靈活變通,能找出很多方法,這里僅舉兩例:

把大括號(hào)放到值里面

把思路調(diào)整過來,既然大括號(hào)不能放在句子模板里面,那我們就放在被填充的值里面:

  1. # 使用.format方法 
  2. >>> name = 'kingname' 
  3. >>> brace = '{' 
  4. >>> print('我的名字是:{name},我的參數(shù)是:{brace}'.format(name=name, brace=brace)) 
  5. 我的名字是:kingname,我的參數(shù)是:{ 
  6.      
  7. # 使用f表達(dá)式 
  8. >>> content_name = 'detail' 
  9. >>> brace = '\{' 
  10. >>> print(f'{content_name}=({brace})$'
  11. detail=(\{)$ 

不要忘記字符串拼接

大家最容易犯的一個(gè)問題就是學(xué)了新的東西,就忘記了舊的,實(shí)際上用字符串拼接也能解決問題:

  1. >>> content_name = 'detail' 
  2. >>> content_json = content_name + '=(\{)$' 
  3. >>> print(content_json) 
  4. detail=(\{)$ 

本文轉(zhuǎn)載自微信公眾號(hào)「未聞Code」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系未聞Code公眾號(hào)。

 

責(zé)任編輯:武曉燕 來源: 未聞Code
相關(guān)推薦

2011-03-10 16:11:01

JavaScript

2021-01-27 21:53:50

版權(quán)保護(hù)隱寫

2021-01-27 11:31:48

物聯(lián)網(wǎng)設(shè)備物聯(lián)網(wǎng)IOT

2024-07-30 08:16:18

Python代碼工具

2010-07-13 17:31:56

SQL Server恢

2015-08-25 10:20:47

云堆棧hypervisor虛擬化

2024-02-20 08:45:13

雙大括號(hào)建立Java Map通用的模式

2013-12-03 16:38:35

vSphere HA虛擬機(jī)

2020-06-14 16:21:06

液體冷卻SLA數(shù)據(jù)中心

2015-08-21 08:59:25

hypervisor云堆棧

2015-09-24 10:08:27

hypervisor

2010-08-03 16:00:08

2019-07-25 10:44:52

2011-03-25 11:39:29

2009-08-14 14:31:43

2020-07-02 14:42:26

網(wǎng)絡(luò)驗(yàn)證業(yè)務(wù)

2020-06-28 11:00:18

大數(shù)據(jù)數(shù)據(jù)湖安全

2022-08-02 10:43:44

智能工廠安全

2013-11-01 09:15:21

2011-12-09 13:38:39

信息防泄漏IP-guard
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)