如何正確保留大括號?

2021-03-02 未聞Code

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

無論是f表達式還是字符串的.format方法,我們都可以使用大括號作為佔位符,來填充數據。例如:

>>> name = 'kingname'
>>> print(f'我的名字是:{name}')
我的名字是:kingname
>>> print(f'1+1的結果為:{1 + 1}')
1+1的結果為:2
>>> salary = 999999
>>> print('我的月薪是:{salary}'.format(salary=salary))
我的月薪是:999999

但現在問題來了,如果我希望在使用f表達式或者.format方法填充內容的同時,又能保留大括號應該怎麼辦呢?

舉個例子,在寫爬蟲的時候,我需要使用正則表達式從當前URL中提取當前的頁數:page=\d{0,3}。但是,對於不同的網站,表示頁數的這個參數名可能是不一樣的,有些是page=xxx,有些是Pag=xxx,有些是pageNo=xxx,有些是p=xxx。所以我想動態生成這個正則表達式。

如果我們直接使用f表達式或者.format方法,就會報錯:

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

為了能夠正常生成正則表達式,可能有人會想到使用古老的%s佔位符:

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

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

實際上,在Python的f表達式和.format方法中,如果你需要保留大括號,那麼只需要寫成大括號套大括號的形式就行了:

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

大括號裡面的第一層大括號會自動失效,變成普通的字符。但如果是大括號套大括號套大括號,那麼最裡面的一對大括號會繼續生效充當佔位符,例如:

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

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

>>> ugly_string = '2層嵌套大括號:{{{{{variable}}}}}'
>>> print(ugly_string.format(variable=variable))
2層嵌套大括號:{{name}}
>>> ugly_string = '3層嵌套大括號:{{{{{{{variable}}}}}}}'
>>> print(ugly_string.format(variable=variable))
3層嵌套大括號:{{{name}}}

假設我們希望最終輸出的字符串裡面,保留n層大括號,那麼在代碼裡面,我們需要寫2n + 1層大括號。大家也看出來了,如果你要這樣寫,數大括號的個數都要把你的眼鏡數瞎。所以,在實際開發中,大括號的層數絕對不要超過2層

以下內容供學有餘力的同學閱讀。

上面講到的方法,適用於大括號成對出現的情況,如果大括號只有半邊,例如有些網站的正文信息是以JSON格式寫在原始碼裡面的,於是我們可以使用正則表達式提取出包含正文的JSON然後進一步處理,一般來說,正則表達式可能是這樣的:content=(\{);。不過,有的網站用的單詞是content,有的網站用的是detail,所以這個地方需要填充,如果我們像往常那樣寫,那麼還是會報錯,例如:

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

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

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

套兩層還是錯。

如果字符串不含反斜槓,我們可以使用f表達式配合引號包住半邊大括號來實現,例如:

>>> name = 'kingname'
>>> print(f'我的名字是:{name},我的參數是:{"{"}')
我的名字是:kingname,我的參數是:{

但問題是,f表達式裡面是不允許出現反斜槓的,否則會報錯:

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

而.format方法支持反斜槓,但它又不支持引號包住單邊大括號的寫法:

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

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

把大括號放到值裡面

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

# 使用.format方法
>>> name = 'kingname'
>>> brace = '{'
>>> print('我的名字是:{name},我的參數是:{brace}'.format(name=name, brace=brace))
我的名字是:kingname,我的參數是:{
    
# 使用f表達式
>>> content_name = 'detail'
>>> brace = '\{'
>>> print(f'{content_name}=({brace})$')
detail=(\{)$

不要忘記字符串拼接

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

>>> content_name = 'detail'
>>> content_json = content_name + '=(\{)$'
>>> print(content_json)
detail=(\{)$

相關焦點

  • 如何去掉括號裡的內容和括號?
    本期小編與大家分享如何去除括號裡的信息以及如何保留括號內的信息呢?1、去除括號信息如下圖表格,如何從客戶信息裡去除括號及裡面的內容?2、保留括號裡的內容若想保留括號裡的內容,同樣可以借用查找和替換功能,選中區域按Ctrl+H打開查找和替換對話框,在查找中輸入代碼:*(,在替換為中不輸入內容,點擊全部替換,之後以同樣的道理刪除右括號內容。以上的技巧,你學會了嗎?
  • word中怎樣輸入大括號 word輸入大括號的方法
    在word編輯文檔的時候,需要輸入標點符號,例如word中怎樣輸入大括號呢?下面介紹輸入大括號的方法。word中怎樣輸入大括號 點擊上方菜單欄中的【插入】選項卡,可以根據需求選擇括號,插入括號後,選擇虛線方框輸入文字。
  • 小括號、中括號、大括號,英文怎麼說?
    一定要讀一下括號裡的內容。寫下來:所有新生需要到會議室,括號,202室,括號完。(2) Brackets 中括號;方括號We type suggestions between brackets to distinguish them from the regular text.
  • 《小括號》試講
    對於一年級學生來說,只要學生知道小括號在算式中的作用,明白有小括號的算式,要先算小括號裡面的,能按照正確的運算順序口算含有小括號的加減混合運算即可。三、《小括號》教學設計教學目標:1.認識小括號,知道有小括號要先算小括號裡面的,能正確計算含有小括號的兩步加、減混合運算。
  • 奧數《巧填算符》第二課時,重點學習如何在算式裡正確填加括號
    奧數《巧填算符》第二課時,重點學習如何在算式裡正確填加括號,使等式成立。大家好,這節課我們繼續學習填算符,這節是《巧填算符》第二課時。繼續學習上節課沒有學完的內容。難題點撥⑦改變一個符號,使得下列等式成立。
  • 如何輸入六角括號「〔〕」
    在我們工作中,六角括號「〔〕」的輸入是經常遇到的,特別是在寫公文文號的時候,六角括號是必用的。然而很多人卻不知道怎麼輸入,不得不用方括號「【】」或者「[]」代替,而這是及其不規範的。六角括號那麼word文檔中打出六角括號真有那麼難嗎?如何才能既快又好的輸入呢?
  • Excel實用技巧分享:小括號常常用,但大括號你用過嗎?
    在excel的使用過程中,我們經常會與小括號打交道,尤其是編輯公式時,經常會用到。但在excel中似乎不管嵌套幾重括號,永遠都是小括號,那麼大括號用到了什麼地方呢?在excel中,用大括號{}包括起來的一組數據叫做數組數據,而其中的每一個數據叫做這個數組數據的元素。例如:數組{「甲」、「乙」、「丙」},其中甲、乙、丙都是這個數組的一個元素。下面,我就用一個實例為大家講解大括號{}在excel中的使用方法。
  • Python的括號家族:方括號、花括號和圓括號的用法總結
    我們來一起回顧一下由列表、字典、元組和集合「四大金剛」,而演變成的由方括號、花括號和圓括號組成的「括號族」。1. 方括號方括號幾乎是所有程式語言的第一符號。這裡的第一,並不是指使用頻率,而是指這個符號展現出的程式語言的內涵和創造力。事實上,就符號的使用頻率而言,方括號也可能排在首位——只是我的直覺,並沒有統計數據支持。
  • 小學數學添括號與去括號,如何擺脫是否要變符號的煩惱
    很簡單,在保證不改變計算結果的情況下,我們給這個算式添加括號。括號表示這是一個整體,不管裡面有多少個數相加減,都把它看成是一個整體。我先算出這部分,再跟別的進行計算。括號是可以改變計算順序的,以後大家在做簡便運算的時候,具體是添括號或去括號,視題目而定。
  • es6 箭頭函數後面的大括號
    let res3 = (r1,r2) => {reurn (r1 + r2)}let r1 = res(1,2);let r2 = res2(1,2);let r3 = res3(1,2);列印出來發現 r1,r3 正確的
  • 摘要:php花括號、大括號{}幾種使用方法的分析
    php花括號、大括號{}幾種使用方法的分析第一種:在函數中的使用例如:function ceshi(){}foreach(){}在函數中常用的方法就是保持數據在作用域範圍的執行第二種:對於那種一直在變化的變量的使用例如:<?
  • 手把手解決三道括號相關的算法題
    (Easy)921.使括號有效的最小插入(Medium)1541.平衡括號串的最少插入(Medium)判斷合法括號串對括號的合法性判斷多次在筆試中出現,現實中也很常見,比如說我們寫的代碼,編輯器會檢查括號是否正確閉合。
  • 有效括號
    有效字符串需滿足:左括號必須用相同類型的右括號閉合。左括號必須以正確的順序閉合。注意空字符串可被認為是有效字符串。有效字符串具有如下規則:任何左括號 ( 必須有相應的右括號 )。任何右括號 ) 必須有相應的左括號 ( 。左括號 ( 必須在對應的右括號之前 )。* 可以被視為單個右括號 ) ,或單個左括號 ( ,或一個空字符串。一個空字符串也被視為有效字符串。
  • 初一上學期,加括號去括號法則,同樣適用於有理數加減乘除法
    1.去括號法則(1)要注意括號前面的符號,它是去括號括號內各項是否變號的依據;(2)去括號時應將括號前的符號連同括號一起去掉;(3)要注意括號前是「-」號時,去掉括號後,括號內的各項都要改變符號,不能只改變括號內第一項或前幾項的符號,而忘記改變其餘的符號
  • Linux系統大括號的作用
    上期小編介紹了Linux系統中括號( )和[ ]括號的作用,這期接著來介紹Linux系統中括號{ }的作用1、Linux系統括號{ }的常規用法1)括號{ }拓展對括號{ }中的文件名做擴展。在括號{ }中,不允許有空白,除非這個空白被引用或轉義。第一種:對括號{ }中的以逗號分隔的文件列表進行拓展。如 touch {a,b}.txt 結果為a.txt b.txt。第二種:對括號{ }中以.
  • 棧:如何實現有效括號的判斷?
    點擊上方藍字,關注:無量測試之道有效括號假如現在要你來解這道題,你會想到怎樣的解法了?這就要用到我們今天要講的「棧」這種數據結構。帶著這個問題,我們來學習今天的內容。2.如何理解「棧」?3.如何實現棧    從剛才棧的定義裡,我們可以看出,棧主要包含兩個操作,入棧和出棧,也就是在棧頂插入一個數據和從棧頂刪除一個數據。理解了棧的定義之後,我們來看一看如何用代碼實現一個棧。  【本文使用  swift語言來編寫代碼,讀者朋友們不要因為程式語言不同而有畏難情緒,重要的是思維和邏輯,語言只是表達方式。
  • 小學如何學標點符號之括號、破折號
    一、括號括號標明文中注釋的部分。括號裡的注釋是比較寬泛的,沒有具體限制,一般不需要讀出來。按照括號在文中的位置可以分為兩類,一類是句內括號,另一類是句外括號。1、句內括號括號裡的話注釋句子裡的某些詞語。如:她(母親)低聲問我:「昨天是幾號?」句內括號只解釋句子的某一部分,如果括號前的正文有點號,應移至括號之後。
  • 奇奇怪怪的知識增加了,大括號的歷史你知道嗎?
    作者 | Michael McMillan譯者 | 彎月,責編 | 夕顏封圖 | CSDN下載自視覺中國眾所周知的標誌代碼塊起始和結尾的大括號是什麼時候開始成為程式語言的一部分的呢?或者更重要的是,代碼塊何時成了編程結構的重要組成部分?我希望通過本文回答這些問題。
  • 一上第五單元:大括號的學問
    大括號其實書上這種可以想像成兩隻手合攏或者像兩隻手張開的符號,不是真正的大括號。可是在加減法列式計算中卻常常有它的身影,所以我們要研究一下這種大括號的學問。它身上有三個位置都標著相應的數。左邊和右邊的數和起來就等於下方的數。那麼,怎麼用算式表示呢?秘密就躲在「問號」的位置上了。?在下方出現時,就好像左手右手一個收起來的慢動作,如果你沒有明白這個動作的要領,還可以來一個右手左手慢動作重播。有時候,?
  • Excel技巧:如何一鍵刪除所有括號及括號中的內容
    但是在給別人發送或者上傳的時候這些括號以及備註就是個很麻煩的事情,因為一個個的刪除太費勁。今天小鷹就正好教給大家一招,讓你們以後能放心的打備註,不需要的時候一鍵就能刪除所有的括號和備註。請看詳細內容:首先打開一個文檔,如下圖所示:能看到,每一個數據裡面都有括號和內容,正常的刪除肯定是一個個的點進去刪掉,費時費力且費心。