亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Regex > 正文

正則表達式的成功習慣

2024-09-07 17:40:13
字體:
來源:轉載
供稿:網友

大家剛接觸正則表達式的時候都會因為正則表達式難于書寫、難于閱讀等各種問題困擾而想放棄,那么你知道要怎么才能學好正則表達式嗎?接下來就讓小編為大家介紹正則表達式的成功習慣吧。

正則表達式難于書寫、難于閱讀、難于維護,經常錯誤匹配意料不到的文本或者錯過了有效的文本,這些問題都是由正則表達式的表現和能力引起的。每個元字符(metacharacter)的能力和細微差別組合在一起,使得代碼不借助于智力技巧就無法解釋。?
?????許多包含一定特性的工具使閱讀和編寫正則表達式變得容易了,但是它們又很不符合習慣。對于很多程序員來說,書寫正則表達式就是一種魔法藝術。他們堅持自己所知道的特征并持有絕對樂觀的態度。如果你愿意采用本文所探討的五個習慣,你將可以讓你設計的正則表達式經受的住反復試驗。?
????本文將使用Perl、PHP和Python語言作為代碼示例,但是本文的建議幾乎適用于任何替換表達式(regex)的執行。?

????一、使用空格和注釋?
????對于大部分程序員來說,在一個正則表達式環境里使用空格和縮進排列都不成問題,如果他們沒有這么做一定會被同行甚至外行人士看笑話。幾乎每個人都知道把代碼擠在一行會難于閱讀、書寫和維護。對于正則表達式又有什么不同呢??
????大部分替換表達式工具都具有擴展的空格特性,這允許程序員把他們的正則表達式擴展為多行,并在每一行結尾加上注釋。為什么只有少部分程序員利用這個特性呢?Perl?6的正則表達式默認就是擴展空格的模式。不要再讓語言替你默認擴展空格了,自己主動利用吧。?
????記住擴展空格的竅門之一就是讓正則表達式引擎忽略擴展空格。這樣如果你需要匹配空格,你就不得不明確說明。?
????在Perl語言里面,在正則表達式的結尾加上x,這樣“m/foo|bar/”變為如下形式:?
m/?
??foo?

??bar?
?/x?
????在PHP語言里面,在正則表達式的結尾加上x,這樣“"/foo|bar/"”變為如下形式:?
"/?
??foo?

??bar?
?/x"?
????在Python語言里面,傳遞模式修飾參數“re.VERBOSE”得到編譯函數如下:?
pattern?=?r'''?
?foo?

?bar?
'''?
regex?=?re.compile(pattern,?re.VERBOSE)?
????處理更加復雜的正則表達式時,空格和注釋就更能體現出其重要性。假設下面的正則表達式用于匹配美國的電話號碼:?
/(?/d{3}/)???/d{3}[-.]/d{4}?
?????這個正則表達式匹配電話號碼如“(314)555-4000”的形式,你認為這個正則表達式是否匹配“314-555-4000”或者“555-?4000”呢?答案是兩種都不匹配。寫上這么一行代碼隱蔽了缺點和設計結果本身,電話區號是需要的,但是正則表達式在區號和前綴之間缺少一個分隔符號的說明。?
????把這一行代碼分成幾行并加上注釋將把缺點暴露無疑,修改起來顯然更容易一些。?
????在Perl語言里面應該是如下形式:?
/???
????/(??????#?可選圓括號?
??????/d{3}?#?必須的電話區號?
????/)??????#?可選圓括號?
????[-/s.]??#?分隔符號可以是破折號、空格或者句點?
??????/d{3}?#?三位數前綴?
????[-.]????#?另一個分隔符號?
??????/d{4}?#?四位數電話號碼?
/x?
????改寫過的正則表達式現在在電話區號后有一個可選擇的分隔符號,這樣它應該是匹配“314-555-4000”的,然而電話區號還是必須的。另一個程序員如果需要把電話區號變為可選項則可以迅速看出它現在不是可選的,一個小小的改動就可以解決這個問題。?

????二、書寫測試?
????一共有三個層次的測試,每一層為你的代碼加上一層可靠性。首先,你需要認真想想你需要匹配什么代碼以及你是否能夠處理錯誤匹配。其次,你需要利用數據實例來測試正則表達式。最后,你需要正式通過一個測試小組的測試。?
?????決定匹配什么其實就是在匹配錯誤結果和錯過正確結果之間尋求一個平衡點。如果你的正則表達式過于嚴格,它將會錯過一些正確匹配;如果它過于寬松,它將會產生一個錯誤匹配。一旦某個正則表達式發放到實際代碼當中,你可能不會兩者都注意到??紤]一下上面電話號碼的例子,它將會匹配“800-555-4000??=?-5355”。錯誤的匹配其實很難發現,所以提前規劃做好測試是很重要的。?
????還是使用電話號碼的例子,如果你在Web表單里面確認一個電話號碼,你可能只要滿足于任何格式的十位數字。但是,如果你想從大量文本里面分離電話號碼,你可能需要很認證的排除不符合要求的錯誤匹配。?
????在考慮你想匹配的數據的時候,寫下一些案例情況。針對案例情況寫下一些代碼來測試你的正則表達式。任何復雜的正則表達式都最好寫個小程序測試一下,可以采用下面的具體形式。?
????在Perl語言里面:?
#!/usr/bin/perl?

my?@tests?=?(?"314-555-4000",?
??????????????"800-555-4400",?
???????"(314)555-4000",?
??????????????"314.555.4000",?
??????????????"555-4000",?
??????????????"aasdklfjklas",?
??????????????"1234-123-12345"???????????
????????????);?

foreach?my?$test?(@tests)?{?
????if?(?$test?=~?m/?
???????????????????/(??????#?可選圓括號?
?????????????????????/d{3}?#?必須的電話區號?
???????????????????/)??????#?可選圓括號?
???????????????????[-/s.]??#?分隔符號可以是破折號、空格或者句點?
?????????????????????/d{3}?#?三位數前綴?
???????????????????[-/s.]??#?另一個分隔符號?
?????????????????????/d{4}?#?四位數電話號碼?
???????????????????/x?)?{?
????????print?"Matched?on?$test/n";?
?????}?
?????else?{?
????????print?"Failed?match?on?$test/n";?
?????}?
}?

????在PHP語言里面:?
<?php?
$tests?=?array(?"314-555-4000",?
???????????"800-555-4400",?
???????????"(314)555-4000",?
???????????"314.555.4000",?
???????????"555-4000",?
???????????"aasdklfjklas",?
???????????"1234-123-12345"?
??????????);?

$regex?=?"/?
????????????/(??????#?可選圓括號?
??????????????/d{3}?#?必須的電話區號?
????????????/)??????#?可選圓括號?
????????????[-/s.]??#?分隔符號可以是破折號、空格或者句點?
??????????????/d{3}?#?三位數前綴?
????????????[-/s.]??#?另一個分隔符號?
??????????????/d{4}?#?四位數電話號碼?
???????????/x";?

foreach?($tests?as?$test)?{?
????if?(preg_match($regex,?$test))?{??
????????echo?"Matched?on?$test<br?/>;";?
????}?
????else?{?
????????echo?"Failed?match?on?$test<br?/>;";?
?????}?
}?
?>;?

????????在Python語言里面:?
import?re?

tests?=?["314-555-4000",?
?????????"800-555-4400",?
?????????"(314)555-4000",?
?????????"314.555.4000",?
?????????"555-4000",?
?????????"aasdklfjklas",?
?????????"1234-123-12345"?????????
????????]?

pattern?=?r'''?
/(??????????????????#?可選圓括號?
??????????????/d{3}?#?必須的電話區號?
????????????/)??????#?可選圓括號?
????????????[-/s.]??#?分隔符號可以是破折號、空格或者句點?
??????????????/d{3}?#?三位數前綴?
????????????[-/s.]??#?另一個分隔符號?
??????????????/d{4}?#?四位數電話號碼?
???????????'''?

regex?=?re.compile(?pattern,?re.VERBOSE?)?

for?test?in?tests:?
????if?regex.match(test):?
????????print?"Matched?on",?test,?"/n"?
????else:?
????????print?"Failed?match?on",?test,?"/n"?

????運行測試代碼將會發現另一個問題:它匹配“1234-123-12345”。?
?????理論上,你需要整合整個程序所有的測試到一個測試小組里面。即使你現在還沒有測試小組,你的正則表達式測試也會是一個小組的良好基礎,現在正是開始創建的好機會。即使現在還不是創建的合適時間,你也應該在每次修改以后運行測試一下正則表達式。這里花費一小段時間將會減少你很多麻煩事。?

????三、為交替操作分組?
????交替操作符號(|)的優先級很低,這意味著它經常交替超過程序員所設計的那樣。比如,從文本里面抽取Email地址的正則表達式可能如下:?
^CC:|To:(.*)?
????上面的嘗試是不正確的,但是這個bug往往不被注意。上面代碼的意圖是找到“CC:”或者“To:”開始的文本,然后在這一行的后面部分提取Email地址。?
?????不幸的是,如果某一行中間出現“To:”,那么這個正則表達式將捕獲不到任何以“CC:”開始的一行,而是抽取幾個隨機的文本。坦白的說,正則表達式匹配?“CC:”開始的一行,但是什么都捕獲不到;或者匹配任何包含“To:”的一行,但是把這行的剩余文本都捕獲了。通常情況下,這個正則表達式會捕獲大量?Email地址,所有沒有人會注意這個bug。?
????如果要符合實際意圖,那么你應該加入括號說明清楚,正則表達式如下:?
(^CC:)|(To:(.*))?
????如果真正意圖是捕獲以“CC:”或者“To:”開始的文本行的剩余部分,那么正確的正則表達式如下:?
^(CC:|To:)(.*)?
????這是一個普遍的不完全匹配的bug,如果你養成為交替操作分組的習慣,你就會避免這個錯誤。?

????四、使用寬松數量詞?
????很多程序員避免使用寬松數量詞比如“*?”、“+?”和“??”,即使它們會使這個表達式易于書寫和理解。?
?????寬松數量詞可以盡可能少的匹配文本,這樣有助于完全匹配的成功。如果你寫了“foo(.*?)bar”,那么數量詞將在第一次遇到“bar”時就停止匹配,而不是在最后一次。如果你希望從“foo###bar+++bar”中捕獲“###”,這一點就很重要。一個嚴格數量詞將捕獲“###bar++?+”。?
????假設你要從HTML文件里面捕獲所有電話號碼,你可能會使用我們上文討論過的電話號碼正則表達式的例子。但是,如果你知道所有電話號碼都在一個表格的第一列里面,你可以使用寬松數量詞寫出更簡單的正則表達式:?
<tr>;<td>;(.+?)<td>;?
????很多剛起步的程序員不使用寬松數量詞來否定特定種類。他們能寫出下面的代碼:?
<tr>;<td>;([^>;]+)</td>;?
????這種情況下它可以正常運行,但是如果你想捕獲的文本包含有你分隔的公共字符(這種情況下比如</td>;),這將會帶來很大麻煩。如果你使用了寬松數量詞,你只要花上很少的時間組裝字符種類就能產生新的正則表達式。?
????在你知道你要捕獲文本的環境結構時,寬松數量詞是具有很大價值的。?

????五、利用可用分界符?
????Perl?和PHP語言常常使用左斜線(/)來標志一個正則表達式的開頭和結尾,Python語言使用一組引號來標志開頭和結尾。如果在Perl和PHP中堅持使用左斜線,你將要避免表達式中的任何斜線;如果在Python中使用引號,你將要避免使用反斜線(/)。選擇不同的分界符或引號可以允許你避免一半的正則表達式。這將使得表達式易于閱讀,減少由于忘記避免符號而潛在的bug。?
????Perl和PHP語言允許使用任何非數字和空格字符作為分界符。如果你切換到一個新的分界符,在匹配URL或HTML標志(如“http://”或“<br/>;”)時,你就可以避免漏掉左斜線了。?
????例如,“/http:////(/S)*/”可以寫為“#http://(/S)*#”。?
????通用分界符是“#”、“!”和“|”。如果你要使用方括號、尖括號或者花括號,只要保持前后配對出現就可以了。下面就是一些通用分界符的示例:?
#…#?!…!?{…}?s|…|…|?(Perl?only)?s[…][…]?(Perl?only)?s<…>;/…/?(Perl?only)??
?????在Python中,正則表達式首先會被當作一個字符串。如果你使用引號作為分界符,你將漏掉所有反斜線。但是你可以使用“r''”字符串避免這個問題。如果針對“re.VERBOSE”選項使用三個連續單引號,它將允許你包含換行。例如?regex?=?"(//w+)(//d+)"可以寫出下面的形式:?
regex?=?r'''?
???????????(/w+)?
???????????(/d+)?
?????????'''?

以上就是小編為大家介紹正則表達式的成功習慣,其實小編建議大家要著重于正則表達式的可讀性,這樣我們才會更加清晰的考慮設計和表達式的結構,才能減少bug和代碼的維護。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲精品日韩久久久| 亚洲香蕉伊综合在人在线视看| 78色国产精品| 日本最新高清不卡中文字幕| 久久天天躁狠狠躁夜夜躁2014| 亚洲第一国产精品| 国产精品1区2区在线观看| 色先锋久久影院av| 亚洲国产成人爱av在线播放| 亚洲精品美女视频| 国产suv精品一区二区| 伊人久久五月天| 最近2019年日本中文免费字幕| 欧美日本中文字幕| 日韩高清a**址| 91网站免费看| 日韩经典中文字幕| 久久久久久久久久婷婷| 欧美麻豆久久久久久中文| 97激碰免费视频| 午夜精品一区二区三区在线视频| 国产精品美女www| 亚洲xxxx在线| 日日噜噜噜夜夜爽亚洲精品| 高清欧美性猛交xxxx| 91精品国产综合久久香蕉最新版| 伊人久久久久久久久久久久久| 欧美乱妇高清无乱码| 91免费人成网站在线观看18| 亚洲欧美在线免费观看| 国产精品老女人精品视频| 91精品国产综合久久久久久蜜臀| 久久久免费在线观看| 欧美性猛交xxx| 精品成人在线视频| 5566日本婷婷色中文字幕97| 亚洲精选一区二区| 成人中文字幕+乱码+中文字幕| 国产亚洲视频在线| 日韩国产欧美精品一区二区三区| 91精品久久久久久久| 神马国产精品影院av| 最近2019中文字幕mv免费看| 亚洲精品成人网| 日韩在线观看网址| 日韩精品免费看| xxxx性欧美| 欧美一级视频免费在线观看| 日韩欧美国产中文字幕| 精品一区二区三区四区| 亚洲国产成人精品一区二区| 黄网动漫久久久| 国产欧美日韩丝袜精品一区| 日韩亚洲在线观看| 欧美在线视频导航| 最近2019年手机中文字幕| 亚洲3p在线观看| 久久精品国产亚洲7777| 热久久视久久精品18亚洲精品| 超碰精品一区二区三区乱码| 亚洲自拍欧美另类| 国产在线日韩在线| 国产裸体写真av一区二区| 欧美美女操人视频| 国产精品扒开腿做| 亚洲天堂男人天堂女人天堂| 久久中文字幕国产| 欧美—级高清免费播放| 成人国产精品av| 国产日韩视频在线观看| 欧美日韩爱爱视频| 国产精品自产拍在线观看| 日韩av在线不卡| 中文字幕日韩欧美在线视频| 丝袜情趣国产精品| 亚洲人精选亚洲人成在线| 欧美三级欧美成人高清www| 国产精品久久久久久久久久99| 成人黄色在线观看| 国色天香2019中文字幕在线观看| 国产精品日韩电影| 亚洲人成自拍网站| 日韩在线高清视频| 91成人国产在线观看| 国产精品久久久一区| 久久精品99久久久久久久久| 亚洲第一网站免费视频| 91久久国产精品91久久性色| 久久97精品久久久久久久不卡| 92看片淫黄大片看国产片| 另类图片亚洲另类| 国产精品劲爆视频| 97超级碰碰人国产在线观看| 成人h视频在线观看播放| 这里只有精品视频| 久久久久久尹人网香蕉| 亚洲成人网久久久| 午夜精品一区二区三区在线播放| 欧美激情国产日韩精品一区18| 亚洲精品国产suv| 中文字幕亚洲一区在线观看| 欧美日韩福利电影| 午夜精品一区二区三区在线| 亚洲视频专区在线| 国产精品日日摸夜夜添夜夜av| 欧美老少做受xxxx高潮| 亚洲综合中文字幕68页| 成人a在线观看| 富二代精品短视频| 日韩精品999| 中文字幕日韩在线观看| 日韩在线观看免费网站| 国产69精品久久久久9| 欧美激情性做爰免费视频| 成人伊人精品色xxxx视频| 亚洲精品98久久久久久中文字幕| 久久在线免费观看视频| 亚洲人成伊人成综合网久久久| 亚洲第一中文字幕在线观看| 欧美成人精品一区二区| 欧美成人中文字幕在线| 国产精品av网站| 国产精品久久久久久五月尺| 欧美在线视频免费播放| 国产成人亚洲精品| 久久91超碰青草是什么| 日本中文字幕久久看| 亚洲激情自拍图| 日韩欧美在线字幕| 日韩av在线免费播放| 亚洲精品久久久久久久久久久久| 国模精品视频一区二区三区| 久久高清视频免费| 亚洲一区二区三区在线免费观看| 欧美在线视频观看免费网站| 91免费人成网站在线观看18| 在线观看亚洲视频| 热久久这里只有精品| 亚洲天堂男人天堂女人天堂| 日韩美女av在线| 国产精品视频白浆免费视频| 亚洲激情免费观看| 国产精品爱久久久久久久| 色综合久久天天综线观看| 日韩亚洲第一页| 亚洲欧美激情在线视频| 91精品啪aⅴ在线观看国产| 午夜精品久久久久久久久久久久久| 亚洲黄色www网站| 97视频在线观看视频免费视频| 中文字幕无线精品亚洲乱码一区| 国产精品视频久久久| 91精品久久久久久久久久入口| 美女av一区二区| 成人午夜一级二级三级| 亚洲最新av网址| 亚洲欧美成人网| 91九色视频在线| 国产精品海角社区在线观看| 狠狠躁夜夜躁人人爽天天天天97| 秋霞午夜一区二区| 国产综合在线视频| www.亚洲一二| 国内精品视频在线|