2020年8月28日 星期五

C 語言 - 正規表示法實作 ( regex.h )

regex.h (Linux 原生, Windows 再說)

    Regex.h 實作主要分 3 階段,regcom, regexec, regfree。
    // 要被批配的 buffer 跟一些參數
    int status, len, i;
    char buf[1024], data[1024];
    getdata(data);

    // 正規表示式的會要先 compile (regcomp())並儲存在 regex_t 此資料結構
    regex_t preg;

    // 設定批配模式的 flag. 
    // REG_EXTENDED ERE (Extended Regular Expression, 不用就是 BRE)
    // REG_ICASE    忽略大小寫
    // REG_NOSUB    不儲存批配後的結果
    // REG_NEWLINE  識別換行符(^$ 這類符號會成每一行的開頭跟結尾), REG_NEWLINE 效力 > eflags
    int cflags = REG_EXTENDED | REG_NEWLINE;

    // 正規表示式的批配樣板
    const char * regex = "Name: ([A-Z a-z]+)\nYear of Birth: ([^\n]*)\n([^:]*: [^\n]*)";

    // pmatch 為 struct 陣列去儲存批配後的結果
    // pmatch.rm_so 批配到的子字串在 target string 的起始 index
    // pmatch.rm_eo 批配到的子字串在 target string 的終止 index
    // nmatch 為宣告 pmatch 的陣列大小
    const size_t nmatch = 10;
    regmatch_t pmatch[nmatch];
    
    // eflags 也會對批配做改動
    // REG_NOTBOL   開頭批配符號(^)永遠批配不到
    // REG_NOTEOL   結尾批配符號($)永遠批配不到
    // REG_STARTEND 是直接使用 pmatch[0] 的 rm_so 跟 rm_eo
    //   作為字串頭尾的 index 然後批配,是為了避免 target string 
    //   中間有終止符(\0) 或 字串太長 strlen() 會 fail.
    int eflags = 0;

    // compile regex 
    if( regcomp(&preg, regex, cflags) != 0 ) {
        puts("regex compile error!\n");
        return;
    }

    // 進行批配 status = 0 代表成功
    status = regexec(&preg, data, nmatch, pmatch, eflags);
    if (status == REG_NOMATCH) {
        printf("No Match\n");
    } else if (status == 0) {
        // pmatch[0] 所指的子字串會是整串
        // pmatch[1], pmatch[2]... 會是括弧裡 sub regex,通常拿來取真正想要的值
        for (i = 0; i < nmatch && pmatch[i].rm_so >= 0; ++i) {
            len = pmatch[i].rm_eo - pmatch[i].rm_so;
            strncpy(buf, data + pmatch[i].rm_so, len);
            buf[len] = '\0';
            printf("match %d :\n%s\n\n", i+1, buf);
        }
    }

    regfree(&preg);
    return;

測試資料 跟 結果

    測試資料
Name: JunYe
Year of Birth: 1993
Gender: Male
    結果
match 1 :
Name: JunYe
Year of Birth: 1993
Gender: Male

match 2 :
JunYe

match 3 :
1993

match 4 :
Gender: Male

Basic (BRE) and extended (ERE) regular expression

    在一些特殊字元處理不一樣, 請參考 GNU的說明
參考資料 :

Related Posts:

  • CSS vertical-align有時候 Input 的 text 或 textarea 有時候預設的對齊可能不盡理想 這時候可以用 vertical-align,這主要是用來對齊圖片的 但有時候你會想讓 textarea 對齊隔壁的物件,因為沒有此參數的話他會對齊 textarea 的底線 textarea { vertical-align:25px; // 向上修正 25px } 也有支援其他參數,但 w3schools 已有列表這邊不在… Read More
  • 網頁開發(2) 利用 Ajax 取的 PHP 值 網頁開發我常利用 Ajax 來連接 PHP以便撈取後端資料 但是 PHP 傳回來的值會是 String 值 而 JavaScript 每個參數都是一個物件,所以辨認不出 PHP傳回來的值 這時就需要 json 來達到取值的效果 首先是 JavaScript 的 Ajax var wanteddata; var requert = $.ajax({ type: "POST", async: false, u… Read More
  • 使用 IE 的理由在公司內部系統,網站會建議使用 Internet Explorer 開啟 原因很簡單,在 IE 裡,一個 html link 可以開啟相同 domain 下的資料夾和檔案 基本上大部分的瀏覽器都會檔,因為安全性的問題。 以 Chrome 為例 <a href="file:///fileserver/test.xls">Test</a> IE 可以直接 Server 上的分享資料夾 只要連結可以轉成… Read More
  • Javascript 做簡單的Table Sorting用 Javascript 作 Table Sorting 這裡寫 2 種自己的做法 第一種 w3schools function sortTable() { var table, rows, switching, i, x, y, shouldSwitch; table = document.getElementById("myTable"); switching = true; /* Make a loo… Read More
  • 改變 Radio Button 的文字 ( Change the text of a radio button )如果你想要在網頁 Update Radio Button 的文字 通常用的 .val(), .text(), .html() 都沒有辦法 這時應該做的是在 HTML 裡把 Radio Button 的文字用一個Label包起來 然後再使用 .next().html() 去Update Radio Button 的文字 這裡的 Label 我使用的是 span HTML :  <input type="r… Read More

0 意見:

張貼留言

Popular Posts