1. 程式人生 > >正則表示式與貪婪規則

正則表示式與貪婪規則

    到這裡,基本上把正則表示式的概念,來源,與shell的區別,本身的不同實現都搞清楚了。這樣,也就不會詢問這個正則表示式在sed下好用,但是使用vim就不行,為什麼?很簡單,元字元的支援問題。
   
     正則表示式有最長匹配的特性,也就是貪婪規則。

    正則表示式是具有貪婪性的,我們從下面這例談起:
已知str="uid=100(guest) gid=100(others) groups=10(users),11(floppy)"
現在想要得到這個字串中的第一個括號內的值,即guest該怎麼辦?假設$str的括號外的內容是不固定的,不能依據uid之類的關鍵字或空格去查詢,所依據的只能是找第一對括號內的內容。

很自然的我們想到用sed,因為sed具有很強的模式匹配的功能,而且能夠將匹配的部分內容強行記下來用於輸出。這樣,我們就會想:
echo $str|sed 's/模式串/1/'
只要模式串寫好了,在匹配的過程中把guest這個字串摳出來,讓sed記住,然後用1輸出就可以了。怎麼寫這個模式串?
.*想要匹配"uid=100"
(...)告訴sed要查詢括弧內的文字
(.*)讓sed記住匹配內容的常用手段,這裡匹配的.*將來就能用1取出來
.*想要匹配" gid=100(others) groups=10(users),11(floppy)"部分
於是我們就寫成了echo $str|sed 's/.*\(.*\).*/1/'
結果呢,得到的是"floppy",為什麼?
正則表示式是有貪婪性的,它總是與最長的可能長度匹配,而且越是排在前面的萬用字元優先順序越高。這一例,第一個.*可以匹配"uid=100(guest) gid=100(others) groups=10(users),11",仍然能保證後面萬用字元的匹配,那一對()匹配了floppy左右的括號,最後的.*自然是可有可無的,所以sed記住的就是floppy。
怎麼辦?我們必須打破正則表示式的貪吃性,用更明確的描述來實現這一點:
我們考慮如果在模式串中第一個.*中告訴sed這個.*是不能含有"("的,不久可以將.*限制到"uid=100"了嗎?這個意思我們完全可以用[^(]*來表達,於是我們修訂剛才的程式碼,變成:
echo $str|sed 's/[^(]*\(.*\).*/1/'
似乎應該很好了,執行的結果卻是"guest) gid=100(others) groups=10(users),11(floppy",為什麼?
原來仍然是正則表達是的貪婪性在作怪,雖然我們有效的阻止了第一個.*的貪吃,但是我們對(.*)中的.*卻未加限制,於是它儘可能匹配了"guest) gid=100(others) groups=10(users),11(floppy",還能保證後面").*"的匹配性。我們再作限制,告訴sed,(.*)中的.*不能含有")",讓它跨不過guest:
echo $str|sed 's/[^(]*\([^)]*\).*/1/'
這回,輸出結果終於是我們想要得"guest"了。

問題解決了,我們也瞭解了正則表示式(或說萬用字元)的貪婪性,於是就可以留個問題給大家,讓大家自己體會體會:
怎麼樣取出str中第二對括號的內容"others"?
怎麼樣取出str中第三對括號的內容"users"?
怎麼樣取出str中第四對括號的內容"floppy"?(這個還用說嗎,就利用正則表示式的貪婪性,我們最開始不就實現它了嘛)

又見michaelds的佳作。
俺來做作業。
str="uid=100(guest) gid=100(others) groups=10(users),11(floppy)"
echo $str|sed 's/[^(]*\([^)]*\)[^(]*\([^)]*\)[^(]*\([^)]*\)[^(]*\([^)]*\
)/2/'

相關推薦

表示式貪婪規則

    到這裡,基本上把正則表示式的概念,來源,與shell的區別,本身的不同實現都搞清楚了。這樣,也就不會詢問這個正則表示式在sed下好用,但是使用vim就不行,為什麼?很簡單,元字元的支援問題。          正則表示式有最長匹配的特性,也就是貪婪規則。     正則表示式是具有貪婪性的,我們從下面這

表示式貪婪匹配貪婪匹配

. :匹配除 "\n" 之外的任何單個字元。要匹配包括 '\n' 在內的任何字元,請使用像 '[.\n]' 的模式 * :匹配0個或多個 使用 .* 的話就可以匹配任意長度的任意字元,但是有時候在使用 .*時就可能匹配不到物品們想要的結果,例: import re

表示式貪婪模式貪婪模式

貪婪模式:能匹配的最大部分   s = "This is a number 234-235-22-4223" r = re.match(r"(.+)(\d+-\d+-\d+-\d+",s) r.groups() ("This is a number 23"

表示式貪婪貪婪模式(II)

貪婪模式 正則表示式在匹配的時候會盡可能多的匹配,直至匹配失敗 如: '123456789'.replace(/\d{3,7}/g,'X') 結果: "X89" 非貪婪模式 讓正

表示式貪婪匹配懶惰匹配

今天用到正則表示式的懶惰匹配,由於開始不是很瞭解,所以一個問題糾結了一天,真正瞭解了就不難了。 例:一個字串“abcdakdjd” regex="a.*?d";    懶惰匹配 regex2="a.*

表示式之--貪婪貪婪模式詳解

“.*”取得控制權後,由A後面的位置開始嘗試匹配,由於是貪婪模式,優化嘗試匹配,一直匹配到字串的結束位置,將控制權交給“"”。“"”取得控制權後,由於已經是字串的結束位置,匹配失敗,查詢可供回溯的狀態,將控制權交給“.*”,由“.*”讓出已匹配字元“.”。重複以上過程,直到後面“"”匹配了C處後面的字元“””

表示式貪婪貪婪

var s='120000|天津市,130000|河北省,210000|遼寧省,220000|吉林省,310000|上海市,320000|江蘇省,330000|浙江省,'; var r = /310000/|(.*?)(?:,)/ r.exec(s); s.match(

表示式貪婪貪婪模式

<script> try{ str="<p>abcdefg</p><p>abcdefghijkl</p>"; re1=str.match(/<p>[\W\w]+?<\/p>/ig); al

JavaScript表示式表單驗證

一.非空驗證 判斷非空 最好還是不要使用trim()方法 有的瀏覽器可能不支援 推薦使用正則表示式 判斷是否為空 // " abc "----->"abc "------>"abc"function trim (txt) { var afterText = txt.replace(/^\s*

表示式的匹配規則

正則表示式的語法規則: 字元:x 含義:代表的是字元x 例如:匹配規則為 "a",那麼需要匹配的字串內容就是 ”a”   字元:\\ 含義:代表的是反斜線字元'\' 例如:匹配規則為"\\" ,那麼需要匹配的字串內容就是 ”\”   字元:\t

GNU/Linux 表示式三劍俠(grep,sed,awk)(精)

相關好文章推薦: GNU 的正則表示式 傳聞中三劍俠的威名響徹雲霄,傳說中若沒有正則表示式的神功,三劍俠也是芸芸眾生,江湖中傳言"欲成劍俠,先練神功",不管傳說或傳聞我都信。 度度果然不是蓋的,一下就拔出了正則的歷史,不看不知道,一看就大有來頭,大約就是國外幾位猛人科學家在搞一個偉大的工程時誕

鳥哥的Linux私房菜基礎篇 第十一章 表示式檔案格式化處理

1. 正則的概念 正則表示式就是處理字串的方法,他是以行為單位來進行字串的處理行為, 正則表示式通過一些特殊符號的輔助,可以讓使用者輕易的達到“搜尋/刪除/取代”某特定字串的處理程式! 2. 基礎

linux學習筆記之shell程式設計(一)表示式字元處理

shell程式設計 基礎正則表示式 正則和萬用字元的區別:正則是包含匹配,匹配檔案內容,grep,awk等支援正則表示式。萬用字元是完全匹配,匹配檔名,例如find,ls不認識正則表示式 ####正則表示式常用的字元(注意區別於萬用字元裡面的符號)#### -*

表示式模式匹配以及捕獲

      首次接觸正則表示式是在工作中接觸到ruby語言指令碼開發的時候,鑑於工作中經常需要對reply內容中的相關欄位進行提取和比較,正則表示式就成為必須掌握的,但僅僅瞭解正則表示式的基本規則還不能完成上面說的這個工作,我們還需要了解跟這個密切相關的另外兩

如何設計一門語言(十)——表示式領域特定語言(DSL)

幾個月前就一直有博友關心DSL的問題,於是我想一想,我在gac.codeplex.com裡面也建立了一些DSL,於是今天就來說一說這個事情。 建立DSL恐怕是很多人第一次設計一門語言的經歷,很少有人一開始上來就設計通用語言的。我自己第一次做這種事情是在高中寫這個傻逼ARPG的時候了。當時做了一個超

PHP表示式的匹配規則

咱們要查詢數字,字母,空白很簡單,因為已經有了對應這些字元的元字元,但是如果匹配沒有預定義元字元的字元集合(比如母音字母a、e、i、o、u),方法很簡單,在方括號裡列出它們就行,如[aeiou]匹配任何一個英文母音字母,[.?! ]匹配各種標點符號以及空格等等,[]匹配單個字元,儘管內部含有好多

第二十二章 Spring cloud Zuul使用表示式指定路由規則

Zuul使用正則表示式指定路由規則 EurekaApplication類 package com.example.demo; import org.springframework.boot.SpringApplication; import org.springfra

python表示式re模組

python中的re模組常用函式/方法 0.正則表示式物件  (re.compile(pattern, flags=0)) 將正則表示式編譯成正則表示式物件,該物件可呼叫正則表示式物件方法如:re.match(),re.search(),re.findall等。 prog = re.c

Linux_Shell_Shell 中的表示式 常用表示式

在Linux Shell 程式設計中,我們常需要用到 正則表示式 進行 檔案的匹配在本篇文章中,我們對Linux shell 中的正則表示式 做一個總結,方便之後的shell 編寫。參考文章:shell程式設計之正則表示式shell script 在if 的判斷條件正則表示式

JAVA語言表示式實現密碼規則設定

<span style="font-size:18px;">密碼規則:長度不能小於6位,必須包含字母和數字。</span>public void say() { Scann