pretty code

顯示具有 Regex 標籤的文章。 顯示所有文章
顯示具有 Regex 標籤的文章。 顯示所有文章

2025年3月15日 星期六

grep 待解謎題

為了找出 instance,理論上同樣的 Tcl regex 應該也是可以用在 grep,但結果就是不行?

改用 -P 就可以?

或是拿掉 \] 也可以找出 non escaped identifier?

容我好好想想。


2025/03/15 晚上更新

還不確定為什麼,但知道解決辦法。

此篇文章給了我靈感,] 如果放在第一個字元(不算 ^),可以不需要跳脫符號,如此一來就可以找到那個 escaped identifier cell 了。

目前確定的是 sed 跟 grep 的行為都是一致。


2025/03/16 更新

原來一直都是我在亂用XD

正規表示法我最早學是在 Perl 裡,但只學些皮毛,後來大部分只用 C 後,便很少使用正規表示法。

後來又陸續多學了一些程式語言,直到現在,真的用 Linux 當開發環境,開始大量的使用 grep awk sed 這些好用的工具後,我終於嘗到苦果了XD

這樣也好,趁這個時候把 regex 的一些細節搞清楚。

當我們嘗試用工具或是程式語言來處理正規表示法的時候,第一件事一定要確定該工具或是該程式語言使用的是哪一種正規表示法!

目前比較熱門的大概有 3 派:

POSIX BRE - Basic Regular Expression
POSIX ERE - Extended Regular Expression
PCRE - Perl Compatible Regular Expression

BRE - grep, vi, sed
ERE - awk, egrep

我個人用的比較偏 ERE。

所以我們應該要 follow ERE 的標準。

而我最習慣也最常用的就是 [a-zA-Z0-9] 這樣的描述,在 BRE or ERE 中稱呼這樣的語法為 Bracket Expression

我這裡用 2004 版的 Spec 來描述,英文比較好懂。


從上面我們可以得知:

01. 特殊符號 .*[\,在 Bracket Expression 中不需要 escaped。
02. ] 因為是終止 Bracket Expression 用,有其特殊性,故要 match 它本身時,我們需要將其放在 Bracket Expression 裡的第一個字元,或是在 ^ 後面。

故我應該只要這樣下就可以了,少了跳脫符號,感覺清楚多了。


至於為什麼我在 Bracket Expression 裡面用 escaped  跳脫那些特殊符號也可以,這點我暫時還不知道是在那個 Spec 的條目中可以解釋就是了。

不過重點是,一樣的語法,我在 Tcl 中卻要跳脫,因為 Tcl 用的是一個叫 ARE 的派別,基本上是 ERE 的延伸,我覺得這是用正規表示法最麻煩的地方。

2024年9月15日 星期日

我不喜歡輸的感覺

Web App 最讓人詬病的就是動態產生網頁內容,尤其是用 Javascript 動態產生的,某種程度上都會大大增加 parsing 的困擾。

有時候只想快速得到一個結果,我還得先用一個類瀏覽器的函式庫取得內容,這不是我喜歡的解決問題方式。

以前曾在網路上看到某位號稱新店寶橋路正規表示法第一的網友,我決定來效法他的作法。

先點選小老婆 Top 50 撥放清單任一首歌,接著使用 Chrome 檢查功能進到 Elements 頁面,在 html tag 處按下滑鼠右鍵 -> Copy -> Copy element,將複製內容另存檔案為 Top_50.txt。


然後就沒有然後了。  

grep -E 'h3 .*aria-label' Top_50.txt | sed -En 's/^\s*<h3.*aria-label="(.* )上傳者.*">/\1/p'


01.郭静 - 陨落(电影《大红包》告白推广曲) (动态歌词) 
02.郭靜 - 夢在遠方 
03.今天起 
04.【純享版】尤長靖/郭靜《氧氣》 治癒系嗓音隔空吟唱太好聽!《天賜的聲音》ep7 純享版no noice /浙江衛視官方hd/ 
05.郭靜 claire kuo - 在樹上唱歌 (官方版mv) 
06.郭靜 claire kuo - 軟綿綿 (官方版mv) 
07.郭靜 - 像我這樣 
08.郭靜 claire kuo - 還有什麼好在意 whatever (官方版mv) 
09.郭靜 claire kuo - 回憶的閣樓 memories of us (官方版mv) 
10.郭靜 claire kuo - 該忘的日子 i am moving on (官方歌詞版) - 韓劇《雲畫的月光》片尾曲 
11.郭靜 claire kuo【深呼吸 take a breath】official lyric video 
12.郭靜 claire kuo - 想個不停 (官方版mv) 
13.郭靜 claire kuo - 不想有遺憾 don’t wanna miss you (官方歌詞版) - 衛視中文台戲劇「長不大的爸爸」插曲 
14.相思弦 
15.逆行的減法 
16.触碰你 
17.在曾有你的地方 
18.郭靜《只為遇見你》【只為遇見你 nice to meet you ost電視劇片頭曲】官方動態歌詞mv (無損高音質) 
19.像风 
20.單身美好 
21.我的小森林 
22.郭靜 claire kuo - 簡單 (官方版mv) 
23.愛情模樣 
24.沙漏 (網劇ᐸ時光教會我愛你ᐳ插曲) 
25.類似快樂的信 (電視劇《戀戀小酒窩》片尾曲) 
26.又是艷陽天 
27.郭靜 claire kuo【消耗寂寞 leave me hanging】official lyric video 
28.悸動 
29.亲爱的你 郭静 [动态歌词/lyrics] 
30.我想要有人為我傷心 
31.算不算 
32.『溫柔女聲』郭靜(guo jing)-拜你所傷(bai ni shuo ci)【我就祝福你,幸福快樂。】#流行歌曲 #動態歌詞 #lyrics #高音質 #好聽 
33.郭靜《一個人勇敢》【我的時代, 你的時代 go go squid2 dt / appledog's time ost電視劇插曲】官方動態歌詞mv (無損高音質) 
34.郭靜 claire kuo - 何日君再來(官方歌詞版)- 電視劇《回家》插曲 
35.郭靜 claire kuo - 小聲音 (官方版mv) 
36.郭靜claire kuo《我非獨自生活》官方版mv 
37.郭靜 claire kuo - 可惜 (官方歌詞版) - 中天電視劇「何以笙蕭默 」片頭曲、 民視偶像劇「星座愛情」獅子女片尾曲 
38.郭靜 claire kuo - 我不是你的那首情歌 not meant to be together (官方版mv) 
39.郭靜 claire kuo - 拍檔 partners (官方版mv) - 電視劇《後菜鳥的燦爛時代》片頭曲 
40.郭靜 claire kuo - 別去問他好嗎 don't let him know (官方版mv) 
41.郭靜 claire kuo - 忘了如何遺忘 how to forget (官方版mv) - 電視劇《聶小倩》片尾曲 
42.郭靜 claire kuo - 每一天都不同 (官方版mv) 
43.郭靜 claire kuo - 明白 (官方版mv) 
44.他爱的梦 
45.《陪你逐風飛翔 to fly with you》郭靜 claire kuo - 越走越遠 farther and farther🥀(英繁中文歌詞 eng lyrics)🤍陪你逐風飛翔 情感插曲 ost 
46.郭靜  claire《慶幸遇見你》【我可能遇到了救星 hi venus ost 電視劇插曲】official lyric video 
47.(mv) 郭靜 (guo jing) - 月亮會記得(yue liang hui ji de) (the moon will remember) ost. 小女霓裳 aka ni chang 
48.最精彩的豔遇 
49.郭靜 claire kuo《暖橘》【我的助理不簡單 never too late ost 電視劇插曲】official lyric video 
50.DuDu好 

最後在聽到第 26 首歌《又是艷陽天》時,搞定此事並寫完更新 Blog

2024/09/15 洗完澡更新

洗澡時才想到忘記補上今天現學現賣的技巧,使用 VIM 在每列前面補上 index。

雖然我也可以都用 VIM 搞定,但我現在只能想到 .recording 2 種方法,操作起來沒有那麼漂亮,故我還是拆成三動來記錄。

01. 先把上面抓到的歌名另存一個檔案,比如 Final_50.txt。 
02. Sed -Ei 's/(.*)/1. \1/g' Final_50.txt
03. 從第 2 列開始,使用區塊模式選取 1 這一個 column,可以用 ctrl + v + G 一口氣選取,然後按下 g + ctrl + a,便會幫每一列的數字自動加 1。
04. Sed -Ei 's/^([0-9]+{1,1}\..*)/0\1/g' Final_50.txt,這裡是幫 1 ~ 9 前面補上 0。

現在就剩下如何都用 VIM 搞定,我猜應該是朝自動向下填入方向去找尋對應指令。

2024/09/16 更新

殘念,這個增加數字的技巧是從 VIM 7.4.754 版本才開始,我們家的工作站版本居然比這還舊?不支援 true color 也就算了,什麼都沒有是怎樣!

另外,對於我這種 parsing 需求來說,也許使用油猴也是個不錯的選擇,改天再來嘗試。

2024/09/21 更新

其實小老婆好聽的歌還可以再追加幾首,有 50 幾首合我口味的歌,真是不簡單呀。

昨天從下午 1:30 開始就邊聽 Top 50 邊 review 這幾天寫的文件,一直到下午 4:30 才聽到《在曾有你的地方》,3 個小時也還聽不到 40 首,不知道為什麼開車時卻覺得很快就輪回一輪了?要不是顧及老婆感受,我應該可以一直聽這歌單不會膩吧XD

另外一個撥放清單的歌混合了我從前到現在聽過覺得好聽的歌,各國語言都有,到目前也才 157 首,一樣可以用我上面 regex 的技巧取出歌名,但在複製 HTML 時,要記得自己用滑鼠拉到最後,不然預設好像只顯示 100 首,另外最後面可能會有幾首是 YouTube 推薦的,但因為是同 CSS 設定,故目前無法有效過濾,也許得用 VIM 手動砍掉推薦影片後面的 HTML 吧。

2024年7月31日 星期三

2024 week 31 新玩意

01. SRAM

M x N

M depth,  M words of memory.
N width,  bits per word.

SRAM 4096X96

wire [95:0] D;
wire [95:0] Q;
wire [11:0] Adder;
reg [95:0] ram[4095:0];

 2^12 = 4096, 12 is the address line width.

Column mux is used to reduce the length of row (4096), it can reduce the area of SRAM ( 讓 SRAM 長寬不要差太多,也可以增加效率 ).

SP means single port SRAM, the port can be used to read or write function.
    clk, addr, en, wen, data.    

2P means two port SRAM, one port for read, one port for write.
    clk_r, clk_w, addr_r, addr_w, en_r, en_w, wen_r, wen_w

DP mean dual port SRAM, two port for read or write function.
    clk_a, clk_b, addr_a, addr_b, en_a, en_b, wen_a, wen_b
    you can read or write at addr_a or addr_b.

02. \d is for PCRE, not for basic regex.

We can use -P when we use grep. 

還好我都習慣使用 [0-9],但偶爾會突然想用 \d,每次都會忘記是 for PCRE。

2024年7月3日 星期三

我果然是 C++ 白癡

想看的 EDA 文章都看得差不多了,今天下午想說來試試將 Python netlist parser porting 到 yosys command。

大概花了 5 個小時,才只完成 80 %,Python code 其實只有 701 行而已。

目前只剩下 save_netlist 相關 code 待移植以及修改 std::getline 呼叫方式。

不想用 namespace std 就必須多打好多 code(std::xxx),有些東西 Standard C++ 也沒有。

至少 regex, read_file line by line 有現成的可用,不過貌似 gcc std::regex constructor 很慢?待確認中。


2024/07/04 更新

早上改完 std::getline 行為後,原本以為可以順風順水,沒想到搞到 12 點多還是有一個莫名的 Segmentation Fault 問題。

下午動用了 GDB,還是看不出是死在自己程式碼的哪個地方,只能看到呼叫一堆的 std::regex 函數?

使用萬能 printf 大法,終於找到出問題的地方。搞到快 4 點多,突然想要 Google 看看,才發現居然是 std::regex 自己的問題,詳此處。 

簡單來說,要做 std::regex_search 的字串不能太長,不然 regex 因為使用遞迴實作,會有 stack 爆掉的問題,難怪 bt 指令看到的都是 regex 函數,Bug 回報的是 100 K 左右就會有問題了,最好的解決方式是改用 boost::regex。

而我手上的 netlist 居然會有 1.5 M 長度的 wire 宣告字串,還不只一條,難怪會死得一塌糊塗!

為了這個不是自己的問題,save_netlist 的功能都還沒 porting,只好之後再說了。 

順便記錄一下 C++ 與 Python 版的差異,為了快速驗證,直接將 netlist 檔案裡 3 條過長的 wire 宣告拿掉。

C++  - 106 seconds, 4G RAM.
Python - 255 seconds, 10G RAM, 離開 Python 約需 7 秒才能回到 shell 提示字元。

因為偷懶,我的 C++ 版本都還沒優化,果然 C++ 還是有其效能上的優勢,不過只是照本宣科 porting 所花的時間都快到 Python 開發時間的一半了。

2024/07/08 更新

早上花了快一個小時將 save_netlist 沒 porting 完的補完,實測結果 yosys C++ 大概也要花個 22 秒左右。

C++ 版本在 save_netlist 函數裡是直接寫檔,除了 instance 的是回傳字串再寫。

Python 版本則是得到一整個 design 字串再一口氣寫檔。

不確定 Python 處理好幾百 MB 的字串效率如何?這應該是一個可以再優化的方向(60 seconds vs 22 seconds)!

下午試了一下,事情跟我想的不一樣,Python 如果只是幾百 MB 的串接字串,一口氣寫檔似乎比一個字串寫一次還來的快,單獨寫的小程式測試結果也是如此?不確定是跟 list 中 iteration 有關還是跟寫檔 buffer I/O 有關?

另外,我測試 yosys command 時繼承的是 Backend,exexute 傳進來的 filename 只有空字串,還需要呼叫 extra_args 才會將檔名從 args 抓出來寫到 filename。

我也順便改了 code,直接用 std::string function 取代 wire regex,也算是避開了 std::regex bug 了。

我是不是全台灣最懂 yosys 的人了XD

2024年3月9日 星期六

正規表示法未解之謎

我有一段簡化過的文字如下,@ 代表空格字元:

@@@@module@ANDGATE@(
@@ANDGATE@gate1@(.A1(A1),@.A2(A2),@.Z(Z));
@@@@module@ORGATE@(
@@ANDGATE@gate1@(.A1(A1),@.A2(A2),@.Z(Z));
@@ORGATE@gate1@(.A1(A1),@.A2(A2),@.Z(Z));


原本打算使用下面的 Regex 來取出各 cell init instance 那行。 

^\s+[^m].*GATE

但因為 \s+ 不會抓最大數量,故 @@@@module 前面 4 個字元也會符合 ^\s+[^m],對正規表示來說前 3 個空白符合 \s+,第 4 個空白符合 [^m] (應該說 Regex 原本用 4 個空白匹配 \s+,但因為發現這樣解讀這行就不滿足了,Regex 為了要盡可能做匹配,故使用了回溯技巧)。

目前還不知道要如何使用 [^m] 這種否定語句,只能使用 ^\s+(AND|OR) 來抓出我要的,但前提是我必須知道所有 case?

一個有 600 多萬行的文字檔,用正面表列確實沒那麼好用,我的正規表示法功力還有待加強XD

2024年1月17日 星期三

神奇的正規表示法

每次都覺得正規表示法很神奇,換了一個工具就有該工具的眉角要注意!

最近沒有意外應該都會在 Linux 下工作,sed 是一個很常用的工具,常用來取代檔案的字串用。

sed 和 grep 一樣,有分 BRE 和 ERE 兩種模式,-E 則代表使用 ERE。

昨天看到一篇文章,剛好有個範例可以練習,沒想到一直試不成功。

下午在寫完簡報後,突然福至心靈的解決了,順便記錄一下。

有一個檔案內容如下:

<html><head><title>Hello World</title>
<body>Welcome to the world of regexp!</body></html>

想要使用 sed 取出非 HTML tag 的內容。

原本是使用 BRE 無法成功
sed -n 's/<.*>\([a-zA-Z !]+\)<\/.*>/\1/p' fileName

改使用 ERE 即可
sed -En 's/<.*>([a-zA-Z !]+)<\/.*>/\1/p' fileName

Note: 上面的 Rex 似乎要把整行都明確表示出來,否則達不到我們要的效果

2021年9月10日 星期五

Named Capture Group in Golang

一直以為在 Regex 的匹配中,可以將 ( ) 裡面的匹配字串取出來是 Javascript 或是 Python 獨有的功能,導致我之前在取 Redfish 的 @odata.type 時,只能用 strings package 去解決我的問題。

今天才了解這是正規表示法的一部份,想當然爾 Golang 當然是有支援的,其用法如下:

re := regexp.MustCompile(`v([0-9]{1,})_([0-9]{1,})_([0-9]{1,})`)
matches := re.FindStringSubmatch("#EventService.v1_7_1.EventService")
fmt.Println(matches)

[v1_7_1, 1, 7, 1]

我們也可以為這些 Group 取名,例如 (?P<MAJOR>[0-9]{1,}),這樣 MAJOR 便會是這個 Group 的名稱,因為在 Golang 還要多一道手續自己作 mapping,故我覺得在這邊取變數的意義就不大了。

2020年4月17日 星期五

正規表示法限定詞之XX肺炎記憶法

因為感染的人
所以科看診的人變
診的結果只有兩種可能

* -> zero or more
+ -> one or more
? -> zero or one

2020年2月1日 星期六

Parse pure text from EPUB.

最近測試時,常常需要盯著螢幕,否則會錯失一些資訊。這時電腦就不能做其他的事,不過一直盯著 console 也很無聊,也不方便看其他技術文件。

乾脆來寫個小程式,把小說 EPUB 裡面的純文字取出來,就能開一個最小視窗放在 console 旁邊,也不會影響測試。

一開始只想簡單用 C 語言來處理就好,不過 EPUB 都是 UTF8 編碼,故不適合用 C 來處理。

本想趁這個機會熟悉一下 python,但還是不想花太多時間在這上面,畢竟我只是拿來打發測試時的無聊時間,重點還是我的測試結果。

想了一下,還是用 node.js 好了,畢竟現在專案後端都是用它,雖然我跟它也不是很熟XD

花了不到半個小時,寫出類似 C 寫法的程式,用起來還算滿意。

只是從來沒有好好使用正規工具,都是把 HTML 硬當字串解析,感覺人家都上太空了,我還在學走路?

大概找了一下,決定使用 parse5 這個模組,反正重點還是測試,不要浪費太多時間。

底下是測試程式及時間,測試檔案為 10,303 bytes :

parse5                             - 解析 HTML Tree 及走訪 Tree 要 29 毫秒,單純走訪只要 11 毫秒。
Regex + string function - 無法分離 Regex 時間,全部要 14 毫秒。

Parse5 Example

const fs = require('fs');
const process = require('process');
const parse5 = require('parse5');

let s = '';

function parseTree(root) {
    if (Array.isArray(root.childNodes)) {
        for (let i = 0; i < root.childNodes.length; i++) {
            parseTree(root.childNodes[i]);
        }
    } 

    if (root.tagName == 'p') {
        console.log(s);
        s = '';
    } else if (root.value) {
        s += root.value;
    }
}

const content = fs.readFileSync('p-06.xhtml', {encoding: 'utf8'});

let t1 = new Date();

const document = parse5.parse(content);

let t2 = new Date();

parseTree(document);

let t3 = new Date();

console.log('\nUsed ms :', t3 - t1, t3 - t2);


Regex Example

const fs = require('fs');
const process = require('process');

function arrangeStr(str) {
    let newStr = '';
    let begin;
    let end;

    while (true) {
        begin = str.indexOf('<');
        if (begin != -1) {
            newStr += str.substring(0, begin);
            end = str.indexOf('>', begin);
            str = str.substring(end+1);  
        } else {
            newStr += str;
            break;
        }
    }
    return newStr;
}

const content = fs.readFileSync('p-06.xhtml', {encoding: 'utf8'});

let t1 = new Date();

let regex = />(.+)</g;

let info;
while ((info = regex.exec(content)) != null) {
    for (let i = 1; i < info.length; i++) {
        console.log(arrangeStr(info[1]));
    }
    console.log('');
}

console.log('\nUsed ms :', new Date() - t1);

2019年6月10日 星期一

UEFI Application - 找出 UEFI 相關函數實作

寫 UEFI Application 時,如果是跟 UEFI 有關的東西,常常需要去 UDKBase 裡翻找,我一般都是使用 "FileSeek v3.3" 這個工具,可以幫助我很快的找到關鍵字。可惜的是,即使發現在某支 .c 檔,如果想要在該檔案中查找相關函數,我目前用的 UltraEdit 並沒有辦法在函式清單中列出來所有函數,這個是跟 UEFI 慣用的函式實作寫法有關,目前至少發現有 2 種寫法,故我後來都是使用 grep 來找出函式名稱。

 Rgex 下法
1. "^\w+\s*\("

兩者的差別在函數名稱後面到左括弧間有無空格,之後如果有新發現再來補充。

2019年2月20日 星期三

Amazon.cn 購買書籍整理

由於 Amazon.cn 的書籍實在是太便宜了
故後來只在信用卡帳單來的時候彙整一筆記帳

這樣的壞處就是容易產生不平帳

本想直接從 Amazon 下載相關訂單比對
但 Amazon 並沒有匯出的功能
只好使用 Python 來 parsing 網頁原始檔

程式只是簡單使用 regex 來 parsing
並沒有使用任何網頁 module
也沒有處理自動登入等功能

還是老話一句,程式夠用就好XD

import html
import re
import sys

def ncr_to_unicode(text):
    words = text.split(';')
    res = ''
    for word in words:
        i = word.find('&#')
        if i == -1:
            word_uni = word
        else:
            s = ''
            if i != 0:
                s = word[:i]
            word_uni = s +  '\\u' + word[i+3:]
        res += word_uni.encode('utf-8').decode('unicode_escape')
    return html.unescape(res)

def main():
    if len(sys.argv) != 2:
        print('amazon.py xxx.html')
        return

    file = sys.argv[1]

    p1 = '<span class="a-color-secondary value">\n +.* (?P<PRICE>.*)\n'
    p2 = '<a class="a-link-normal" href="\/gp\/product\/.*>\n +(?P<NAME>[a-zA-Z0-9&]+.*)\n'

    f = open(file, 'r', encoding='utf-8')
    data = f.read()
    f.close()

    prog = re.compile(p2)
    names = prog.findall(data)

    prog = re.compile(p1)
    others = prog.findall(data)

    out = open('book.txt', 'a', encoding='utf-16')

    for x in range(len(names)):
        bookName = ncr_to_unicode(names[x])
        buyDate = others[3*x + 0]
        price = others[3*x + 1]

        s = '%s\t%s\t%s' % (buyDate, price, bookName)

        print(s)
        out.write(s)
        out.write('\r\n')

    out.close()

if __name__ == "__main__":
    main()


購買時匯率介於 4.32 ~ 4.60
2019年1月29日 9.99 程序员的数学思维修炼(趣味解读)
2019年1月16日 14.99 面向机器智能的TensorFlow实践 (智能系统与技术丛书)
2018年12月28日 12.99 小岛经济学:鱼、美元和经济的故事
2018年12月27日 0.10 桂林古本傷寒雜病論 (Traditional_chinese Edition)
2018年12月19日 24.99 函数式编程思维 (图灵程序设计丛书)
2018年12月19日 47.99 古龙经典72册(读客熊猫君出品。)(读客知识小说文库)
2018年12月19日 17.99 东野圭吾:解忧杂货店
2018年12月19日 9.99 东野圭吾:新参者 (东野圭吾作品)
2018年12月19日 7.99 火星救援(2016雨果奖影视作品奖、最佳新人作家奖获奖作品!!)
2018年12月12日 15.40 扶阳讲记 (卢火神医集系列)
2018年12月11日 31.59 囚徒健身: 用失传的技艺练就强大的生存实力
2018年12月1日 2.99 梦幻花 (东野圭吾最新悬疑小说)
2018年12月1日 13.56 自控力
2018年11月29日 9.35 圆运动的古中医学 (中医名家绝学真传丛书)
2018年11月29日 7.79 四圣心源 (黄元御医书精华)
2018年11月29日 35.40 海龟交易法则(揭秘普通人如何成为伟大的交易员)
2018年11月27日 31.85 C和指针(异步图书) (C和C++经典著作)
2018年11月24日 14.96 李经梧太极内功及所藏秘谱
2018年11月24日 14.60 睡眠革命 (未读·生活家)
2018年11月23日 11.44 走近中医:对生命和疾病的全新探索
2018年11月23日 5.99 思考中医:对自然与生命的时间解读
2018年11月23日 7.91 初中数学思维方法全解与精练 (新课标·全解与精练系列)
2018年11月23日 15.60 小言《黄帝内经》与生命科学
2018年11月22日 24.01 JavaScript语言精粹(修订版)
2018年11月22日 7.91 湖畔(继白夜行后又一力作,对当代社会与家庭严厉的拷问)

2019年1月25日 星期五

grep 小技巧

目前因為測試
故手上有好幾千筆的開機資料

正常情況下只要 parse 一次即可
故時間還可以接受

但是如果要測試 Server 的功能時
這幾千筆的資料便會拖慢測試速度

grep 有一個參數可以方便我們擷取前幾筆的資料
這樣一來就可以產生出可供人工使用的測試資料了
輸出控制:
  -m, --max-count=NUM       在達到 NUM 符合項目後停止

Usage:
grep ".*" --text -m 30000 Reboot.log > test.log

2018年12月12日 星期三

Python 正規表示式用法

Python 在使用 re 時
記得 pattern 要包含其他需要的字串(.*)

舉例來說
我想尋找每行有 "ERROR " 字眼的字串
re pattern 要寫成 "ERROR .*"
否則找到的都會只有 "ERROR " 本身

底下是針對規則的進階用法
把想要特別提出來的寫成如下形式
(?P<name>正規表示式)

就可以更方便的找出對應的資料


import re

ERROR_PATTERN = 'ERROR.*Test: (?P<TEST>[0-9]+).*Address: (?P<ADDR>[0-9A-F]+)'

errMsg = '''
2068-09-12 22:06:48 - [MEM ERROR - Data] Test: 6, CPU: 1, Address: 101B8F330, Expected: FFFF5FFF, Actual: FFFFDFFF
2068-09-12 22:06:48 - [MEM ERROR - Data] Test: 6, CPU: 1, Address: 103B8F310, Expected: FFFF5FFF, Actual: FFFFDFFF
2068-09-12 22:06:50 - [MEM ERROR - Data] Test: 6, CPU: 3, Address: 119FEA5F0, Expected: FFFF7FDF, Actual: FFFFFFDF
2068-09-12 22:06:50 - [MEM ERROR - Data] Test: 6, CPU: 3, Address: 11BFEA5D0, Expected: FFFF7FDF, Actual: FFFFFFDF
2068-09-12 22:20:53 - [MEM ERROR - Data] Test: 6, CPU: 2, Address: 10466E930, Expected: FFFF7FEF, Actual: FFFFFFEF
2068-09-12 22:20:53 - [MEM ERROR - Data] Test: 6, CPU: 2, Address: 10666E910, Expected: FFFF7FEF, Actual: FFFFFFEF
2068-09-12 22:20:53 - [MEM ERROR - Data] Test: 6, CPU: 0, Address: 10D6CC9B0, Expected: FFFF7EFF, Actual: FFFFFEFF
2068-09-12 22:20:53 - [MEM ERROR - Data] Test: 6, CPU: 0, Address: 10F6CC990, Expected: FFFF7EFF, Actual: FFFFFEFF
'''

res = re.findall(ERROR_PATTERN, errMsg)

print(res)


輸出結果
[
    ('6', '101B8F330'), 
    ('6', '103B8F310'), 
    ('6', '119FEA5F0'), 
    ('6', '11BFEA5D0'), 
    ('6', '10466E930'), 
    ('6', '10666E910'), 
    ('6', '10D6CC9B0'), 
    ('6', '10F6CC990')
]

2018年2月26日 星期一

grep binary 檔案

使用 grep parse log 時
如果 log 裡面有非 ASCII 字元時,比如說 0x00
此時 grep 會誤認為檔案為 binary 檔案
故無法 line by line 顯示

此時只要簡單加上 --text 選項即可

2017年9月6日 星期三

Javascript 正規表示法

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp

純 Javascript 中使用正規表示法

regex 是一個正規表示
str 是一個字串
info 是執行 exec 回傳的 array

因為我們有用 "( )" 圈住數字
故 array[1] 會是 123
而 array[2] 會是 456


程式範例
var regex = /(\d+) (\d+)/;
var str = '123 456';
var info = regex.exec(str);

for (var i = 0; i < info.length; i++) {
    console.log(i, info[i]);
}

執行結果
0 '123 456'
1 '123'
2 '456'

如果字串中有 1 個以上要匹配的地方,我們可以考慮使用 flag 'g'
如果忘記加上 'g',程式便會進入無窮迴圈,因為 regex.lastIndex always = 0
var regex = /(\d+) (\d+)/g;
var str = '123 456; 789 100';

var info;
while ((info = regex.exec(str)) != null) {
    console.log(regex.lastIndex);
    for (var i = 0; i < info.length; i++) {
        console.log(i, info[i]);
    }
}

執行結果
7
0 '123 456'
1 '123'
2 '456'
16
0 '789 100'
1 '789'
2 '100'

2016年7月22日 星期五

grep examples

# 挑出超過 1000 ms 的資料
110.txt: 100%    800 (longest request)
111.txt: 100%   2538 (longest request)
112.txt: 100%   1209 (longest request)
113.txt: 100%   2341 (longest request)
114.txt: 100%    829 (longest request)
115.txt: 100%   2506 (longest request)
116.txt: 100%    829 (longest request)
117.txt: 100%   2372 (longest request)
118.txt: 100%    862 (longest request)
119.txt: 100%   5681 (longest request)
120.txt: 100%    803 (longest request)

ANS: grep -E "%\s{3}\S"
前面一定要加入 % ,不然就如圖片所示,有 4個空白的列也會符合。