1. 程式人生 > >grep在一個文字中查詢符合條件的文字

grep在一個文字中查詢符合條件的文字

好久沒有寫過正則的東西了。今天說說零寬斷言,我看過網上那篇著名的《正則表示式30分鐘入門》,那時應該是08年左右,我還覺得正則太難了。《編譯原理及實踐》中講到了正則,但這門課程本身我就學得亂七八糟。

零寬斷言的英文原文:

Zero-WidthAssertions

     看到網上的文章,我覺得零寬斷言講的還是不夠詳細。我覺得以下的理解或許可以簡化零寬斷言的概念。簡而言之,零寬斷言的作用就是去掉你不關心的部分內容。

舉個例子:在linux系統上面獲取或者本機的IP地址

ifconfig可以看到啟用的網路介面的詳細資訊,那麼肯定我們需要藉助grep來過濾出IP地址了。因為伺服器有多個介面,我只關心公網IP的地址,可以看到eth下面一行顯示了IP地址。

ifconfig | grep eth -A 1 得到如下的結果:

eth0     Link encap:Ethernet  HWaddr 12:31:43:03:98:2C 
         inet addr:10.150.151.218 Bcast:10.150.151.255  Mask:255.255.254.0

觀察到ip地址的前面是addr:這幾個字元,於是再來過濾

 ifconfig | grep eth -A 1 | grep -oP'addr:[\d\.]+' 得到新的結果:

addr:10.150.151.218

這裡我們使用了-o和-P選項,指定-o是因為grep預設是顯示匹配的那一行,我們只關心精確匹配的部分而不是整行。至於-P表明後面的pattern是perl相容正則表示式,因為pcre才支援零寬斷言。

可以看到結果中多了addr:這幾個字元,這個時候該零寬斷言大顯身手了。不想要addr:這幾個字元,那我們就去掉他。如下方式:

 ifconfig | grep eth -A 1 | grep -oP'(?<=addr:)[\d\.]+'

注意粗體部分,這個東西的英文名字我不太清楚,但有人這樣翻譯:零寬度正回顧後發斷言,看到這個名字能不暈嗎。其實我們不關心它叫什麼,我們只關心它的作用。實際操作的時候,我們可以這樣做,比如我想匹配addr:後面跟一個ip地址的情況(前文所言),但我只想要ip地址。那我們先來普通的過濾得到一個帶addr:的結果,最後再去掉那些我們不想要的部分就可以了。至於怎麼去掉,如果是去掉模式前面的部分,用(?<=xxx),如果是模式後面的部分,用(?=xxx),其中xxx就是你不想要的那些內容。不太好記住?實際上是比較一致的,左邊的多了一個<,正好是向左的箭頭。

至於有人又說到匹配方式的問題,個人覺得也不用太關心。我們不需要去關心正則表示式的具體實現,只要記住正則是貪心的就對了。所以以下命令得到的結果也就不奇怪了。

echo 'cooking singing' | grep -oP "[a-z]*(?=ing)"      ----------->cook sing

echo 'abcdefgabc' | grep -oP'(?<=abc).*'          -----------------> defgabc

 零寬斷言的作用跟正則中的錨位置相同,比如我想要尋找以abc開頭的行,很自然我們會想到^abc,同樣,abc結尾的行--abc$,但我們並不關心^$本身,他只是我們匹配模式的錨點。零寬斷言的作用正是如此,比如匹配abc後面跟了一個xxx,但我只要xxx不要abc,那麼就是(?<=abc)xxx。所謂零寬就是寬度為0,我們要拋棄掉這樣的錨點。

至於負向零寬斷言,意思是說在我們的錨點周圍不存在這樣的匹配。還是舉行首和行尾的情況,我們要尋找不是abc開頭的行--^[^a][^b][^c]。這次我沒有自然想到,一時還沒有反應過來,所謂開頭不是abc的意思就是第一個字元不是a,第二個字元不是b,第三個字元不是c,我現在還只知道前面的那種寫法。這句話也可以說成是,行首後面不是abc。類似的不以abc結尾的行,[^a][^b][^c]$。那我想要找abc後面不是xxx的情況呢?這就要用到零寬斷言了,因為行首在正則中預設就是一個錨點,但是你自定義的abc顯然不是。與零寬斷言類似,只不過把=換成!就行了,比如(?

犯了一個巨大的錯誤。(?

寫道這裡,我又想起了vim的正則,因為vim的正則確實跟perl不相同,有時候用著也犯暈。以下是對比:

Lookahead and Lookbehind Zero-Width Assertions
Positive and Negative Lookahead
Positive and Negative Lookbehind
Lookaround Is Atomic

相關推薦

grep一個文字查詢符合條件文字

好久沒有寫過正則的東西了。今天說說零寬斷言,我看過網上那篇著名的《正則表示式30分鐘入門》,那時應該是08年左右,我還覺得正則太難了。《編譯原理及實踐》中講到了正則,但這門課程本身我就學得亂七八糟。 零寬斷言的英文原文: Zero-WidthAssertions      看到網上的文章,我覺得零寬斷

Linux grep 命令檢視符合條件文字的相近幾行

查日誌時,grep 到自己想要的行之後,還想看下符合條件的附近日誌記錄 man grep 發現果然已經有這個引數 Context Line Control -A NUM, --after-context=NUM Print NUM l

grep-查詢符合條件的字串

grep:         查詢行裡符合條件的字串 grep退出狀態:     0: 表示成功;     1: 表示在所提供的檔案無法找到匹配的pattern;     2: 表示引數中提供的檔案不存在。 引數說明:         -n: 在輸出符合條件的行時把行號顯示出

更新表字段,從另一個查詢出來

code upd 另一個 查詢 print ng- ble where sql UPDATE t SET t.Premium = (SELECT TOP 1 Max( t2.Premium ) FROM dbo.TableName t

js 如何id為xx的div包含的ul符合條件的li元素

需求:首頁左側有導航欄,點選導航欄,會出現一個div,div中有很多可以跳轉的頁面,但是有的div需要新增一個滾輪,所以需要找到這個div,然後新增一個特殊的類名 重點程式碼就是: var div=document.getElementById(“nav_s

postgresql 在某個記錄查詢滿足條件的欄位 findfield

最近,在一個Insert SQL時報欄位長度不夠,但又沒指出哪個欄位,表的欄位數很多,看了好久都沒找出是哪個欄位,心想有什麼辦法能按指定條件過濾當前記錄的所有欄位不就能找出我想要的欄位嗎?昨天終於用hstore寫出了一個滿足需求的函式,特記錄如下,備查。 --usage:

筆試題:在一個字串查詢子字串的個數

題目:在一個字串中查詢子字串的個數。 要求:兩個字串之間以空格隔開,前一個為字串,後一個為要查詢的子字串。結果輸出字串中包含的子字串的個數。 例如:輸入:abcdssdfabc abc

一個字串查詢子字串出現的次數

public static void countSubstring(){ //方法1:遍歷法 String s1="abcdabc"; String s2="ab"; int count

mysql 對錶資料進行求和分組並在結果篩選符合條件的資料 having group by count

查詢table表查詢每一個班級中年齡大於20,性別為男的人數 select COUNT(*)as '大於20歲人數',classid  from Table1 where sex='男' group by classid,age having age>20 --需

一個字串查詢子字串出現的次數(兩種方法)(遍歷查詢和切割判斷)

                /** * 思路:開始找,如果返回-1,結束程式 * 否則,計數+1,再繼續從新的位置開始找,直到找不到 */ String str = "www.baidu.com/www.sina.com"; String s

ORACLE SQL: 從一個查詢資料插入另一個

insert into expertinfo (expertid,expertname,expertcode,sex,enabled) select primarykey as expertid, name as expertname,

【C語言】模擬實現strchr函式.即在一個字串查詢一個字元第一次出現的位置並返回

//模擬實現strchr函式.即在一個字串中查詢一個字元第一次出現的位置並返回 #include <stdio.h> //#include <string.h> #includ

淺談sql server把一個查詢出來的資料插入到另外一個

1、 insertintoA([id], ids,[name], type, time) select[id],null,[name],'dd',getdate()fromBwheretype='dd' 2、 DECLARE @num int,@i int; SET @

一個字串查詢子串,並返回該子串第一個字母所在位置

題目:在字串S中查詢字串T,並返回T首字母在S中的位置、程式碼:int Index(string s, string t, int pose){    int n,m,i=0;  n=StrLength(s);   m=StrLength(t);  string sub; w

java8stream操作:從集合獲取符合條件的元素

List<Student> students = new ArrayList<>(); students.add(new Student(1,"張三",

mybatis查詢符合條件的記錄數時錯誤there is no getter for property named。。。

做分頁查詢時,查詢符合條件的總記錄數報錯: java.lang.RuntimeException: org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ib

一個集合查詢最大最小的N個元素——Python heapq 堆資料結構

Top N問題在搜尋引擎、推薦系統領域應用很廣, 如果用我們較為常見的語言,如C、C++、Java等,程式碼量至少也得五行,但是用Python的話,只用一個函式就能搞定,只需引入heapq(堆佇列)這個資料結構即可。今天偶然看到這個庫,特意記下之。 先看一個例子: 複製

【c語言】模擬實現strchr函式,功能:在一個字串查詢一個字元第一次出現的位置,如果沒有出現返回NULL

// 模擬實現strchr函式,功能:在一個字串中查詢一個字元第一次出現的位置,如果沒有出現返回NULL #include <stdio.h> #include <assert.h> char const* my_strchr(char cons

Java——在一個字串查詢一個子串,計算出來這個子串在字串出現的次數。

引入包:import java.util.Scanner;main函式:public static void main(String[] args){Scanner s = new Scanner(Sy

LeetCode 86 | 連結串列基礎,一次遍歷處理連結串列所有符合條件的元素

本文始發於個人公眾號:**TechFlow**,原創不易,求個關注 今天是LeetCode專題第53篇文章,我們一起來看LeetCode第86題,Partition List(連結串列歸併)。 本題的官方難度是Medium,點贊1276,反對296,通過率大約41%。總體來說,這題質量一般,通過率有點高