1. 程式人生 > >linux c下的字串正則替換

linux c下的字串正則替換

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

//regex
#include <regex.h>


//cns_reg函式的返回型別
typedef struct _reg_rtn_struct
{
   int rtn;       //成功與否標誌0 成功, 1失敗
   int pstart;    //匹配到的子串開始位移
   int pend;      //匹配到的子串尾部位移
} reg_rtn_struct;


/**
*
* 正則表示式查詢函式
*/
reg_rtn_struct cns_reg(const char *str,  const char *pattern)
{
    reg_rtn_struct reg_rtn_struct_var;

    int          z;            //status
    int          pos;          //配置處的位置
    int          cflags = REG_EXTENDED;   //compile flags
    regex_t      reg;          //compiled regular expression
    char         ebuf[128];    //error buffer
    bzero(ebuf, sizeof(ebuf));
    regmatch_t   pm[10];       //pattern matches 0-9
    bzero(pm, sizeof(pm));
    const size_t nmatch = 10;  //The size of array pm[]

    //編譯正則表示式
    /**
     *
     * @param const char*  pattern         將要被編譯的正則表示式
     * @param regex_t*     reg             用來儲存編譯結果
     * @param int          cflags          決定正則表示式將如何被處理的細節
     *
     * @return  success    int        0    並把編譯結果填充到reg結構中
     *          fail       int        非0
     *
     */


    z = regcomp(&reg, (const char*)pattern, cflags);

    if(z)   //此處為 if(z != 0), 因為C語言裡0永遠為非(False), 任何非0值都為真(True)
    {
       regerror(z, &reg, ebuf, sizeof(ebuf));
       perror("reg1");
       fprintf(stderr, "%s: pattern '%s'\n", ebuf, pattern);
       reg_rtn_struct_var.rtn    = 1;
       reg_rtn_struct_var.pstart = -1;
       reg_rtn_struct_var.pend   = -1;

       regfree(&reg);
       return reg_rtn_struct_var;
    }

    /**
     *
     * reg     指向編譯後的正則表示式
     * str     指向將要進行匹配的字串
     * pm      str字串中可能有多處和正則表示式相匹配, pm陣列用來儲存這些位置
     * nmacth  指定pm陣列最多可以存放的匹配位置數
     *
     * @return 函式匹配成功後,str+pm[0].rm_so到str+pm[0].rm_eo是第一個匹配的子串
     *                           str+pm[1].rm_so到str+pm[1].rm_eo是第二個匹配的子串
     *                           ....
     */
    z = regexec(&reg, str, nmatch, pm, 0);

    //沒有找到匹配資料
    if(z == REG_NOMATCH)
    {
       reg_rtn_struct_var.rtn    = 1;
       reg_rtn_struct_var.pstart = -1;
       reg_rtn_struct_var.pend   = -1;

       regfree(&reg);
       return reg_rtn_struct_var;
    }
    else if(z)  //if(z !=0)
    {
       perror("reg3");
       regerror(z, &reg, ebuf, sizeof(ebuf));
       fprintf(stderr, "%s: regcomp('%s')\n", ebuf, str);

       reg_rtn_struct_var.rtn    = 1;
       reg_rtn_struct_var.pstart = -1;
       reg_rtn_struct_var.pend   = -1;
       regfree(&reg);

       return reg_rtn_struct_var;
    }

    /*列出匹配的位置*/
    if(pm[0].rm_so != -1)
    {
       reg_rtn_struct_var.rtn    = 0;
       reg_rtn_struct_var.pstart = pm[0].rm_so;
       reg_rtn_struct_var.pend   = pm[0].rm_eo;
    }

    regfree(&reg);
    return reg_rtn_struct_var;
}


/*
* 正則表示式替換函式
*/
char *cns_str_ereplace(char *src, const char *pattern, const char *newsubstr)
{
    //如果pattern和newsubstr串相等,則直接返回
    if(!strcmp(pattern, newsubstr))   //if(strcmp(pattern, newsubstr)==0)
       return src;

    //定義cns_reg的返回型別結構變數
    reg_rtn_struct  reg_rtn_struct_var;
    int rtn    = 0;   //reg_rtn_struct_var.rtn
    int pstart = 0;   //reg_rtn_struct_var.pstart
    int pend   = 0;   //reg_rtn_struct_var.pend


    //把源串預dest
    char *dest=src;  //替換後生成的串指標
    char *pstr=src;  //當找到串時,pstr就指向子串後面的地址從而標識下一個要查詢的源串

    //用於malloc的臨時記憶體區
    char *tmp;
    char *new_tmp_str=dest;

    int new_tmp_str_len=0;  //new_tmp_str相對於dest地址開始處的長度


    //開始迴圈替換src串中符合pattern的子串為newstr
    while(!rtn)
    {
        reg_rtn_struct_var=cns_reg(new_tmp_str, pattern);

        rtn    = reg_rtn_struct_var.rtn;
        pstart = reg_rtn_struct_var.pstart;
        pend   = reg_rtn_struct_var.pend;

        if(!rtn)
        {
            //分配新的空間: strlen(newstr):新串長  pend-pstart:舊串長
            tmp=(char*)calloc(sizeof(char), strlen(dest)+strlen(newsubstr)-(pend-pstart)+1 );

            //把src內的前new_tmp_str_len+pstart個記憶體空間的資料,拷貝到arr
            strncpy(tmp, dest, new_tmp_str_len+pstart);

            //標識串結束
            tmp[new_tmp_str_len+pstart]='\0';

            //連線arr和newstr, 即把newstr附在arr尾部, 從而組成新串(或說字元陣列)arr
            strcat(tmp, newsubstr);

            //把src中 從oldstr子串位置後的部分和arr連線在一起,組成新串arr
            strcat(tmp, new_tmp_str+pend);

            //把用malloc分配的記憶體,複製給指標dest
            dest = strdup(tmp);

            //釋放malloc分配的記憶體空間
            free(tmp);

            new_tmp_str_len = new_tmp_str_len + pstart + strlen(newsubstr);
            new_tmp_str=dest+new_tmp_str_len;
        }
    }

    return dest;
}


int main()
{
  //測試正則表示式
  char str[]="1love2love3love4love5love6love!";

  reg_rtn_struct reg_rtn_struct_var;

  char *newstr=cns_str_ereplace(str,"love","daiwenhai");
  puts(newstr);

  return 0;
}


相關推薦

linux c字串替換

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> //r

linux C語言處理表達式

man cte 得到 rsquo like pre 首地址 添加 有效 Linux下C語言處理正則表達式——regex.h 具體函數介紹 編譯正則表達式函數 int regcomp(regex_t *preg, const char *re

pycharm對字串進行替換

利用Pycharm的替換功能,對字串進行格式化的操作,例如,將瀏覽器中複製過來的requests headers 字串通過替換格式化成一個字典。 工具/原料 pycharm 正則表示式 方法/步驟 首先,複製所有Headers欄位,貼上到pych

LinuxPOSIX表示式API使用

一、概述 在Linux環境中,經常使用正則表示式,如grep、sed、find等等,目前正則表示式有2中不同的標準,分別是Perl標準和POSIX標準,這2種風格,大體相同,稍有差別。在 C/C++的標準庫均不支援表示式,不過在C++11標準中,貌似引入了boost的正則庫,在Li

preg_replace() 替換所有符合條件的字串

PHP preg_replace() 正則替換,與Javascript 正則替換不同,PHP preg_replace() 預設就是替換所有符號匹配條件的元素 需要我們用程式處理的資料並不總是預先以資料庫思維設計的,或者說是無法用資料庫的結構去儲存的。 比如模版引擎解析模版、垃圾敏感資訊過濾

替換re.sub 替換字串中多個位置

import re time = ' 2018年08月27日 13:17:26' [\u4e00-\u9fa5]為unicode編碼,並且剛好是 中文編碼的開始和結束的兩個值 ‘sub中’ ‘第一個引數表示字串中需要替換的內容,’ ‘第二個引數表示想要替換的成什麼’ ‘第三個引數表示

替換字串的全形 半形標點符號

                感謝【火龍果】,欽佩他的研究精神。http://topic.csdn.net/u/20080925/15/41b814bf-fcaf-4b37-be91-10561a102768.html測試程式碼如下:class T {publicstaticvoid main(String

python含中文字串表示式的編碼問題

前言Python檔案預設的編碼格式是ascii ,無法識別漢字,因為ascii碼中沒有中文。所以py檔案中要寫中文字元時,一般在開頭加 # -*- coding: utf-8 -*- 或者 #coding=utf-8。這是指定一種編碼格式,意味著用該編碼儲存中文字元(也可以是

字串aaaa......bbbb....ccc...dddddd用替換為abcd

public static void main(String[] args) { String s = "aaaa......bbbb....ccc...dddddd"; String s2 = s.replaceAll("\\.+",""); Syste

C#/JS 利用表示式 替換/刪除 img 裡面的 width height

JS: function test() { var str = "<img title=\"\" alt=\"\" align=\"\" src=\"/kindeditor/attached/image/20161214/20161214162

Python 替換字串

說明 需求: 1. 替換給定字串中符合正則匹配的子串。 2. 使用者配置增加、刪減替換規則方便。 3. 基於裝飾器模式實現。 實現 基於re包和裝飾器模式實現。 參考裝飾器模式,這資料挺不錯的,有人把設計模式用python都實現了一遍。 郵箱

linux練習表示式

1.什麼是正則表示式 在做文書處理或編寫程式時,用到查詢、替換等功能,使用正則表示式能夠簡單快捷的完成目標。簡單而言,正則表示式通過一些特殊符號的幫助,使使用者可以輕鬆快捷的完成查詢、刪除、替換等處

js javascript 處理含有反斜槓等特殊符號的字串替換"\"反斜槓,替換"\"反斜槓...

如果要實現替換"\"反斜槓的操作,可以直接將原字串利用此方法先編碼,再替換為相應字元的編碼,最後解碼就得到目標字串了.任何特殊字元編碼也都可用此程式獲得,如"\"單反斜槓 %5C"|" %7C回車 %0D%0A空格 %20雙引號 %22"&" %26a

linux sh指令碼使用獲取行中子字串

[email protected]:/var/www/edm/ssh# vi assay.sh#!/bin/bash# get args[1]logStr=$1# get sender# the exrep must have (),and all must escape# 在sh中,:並不是"特

php 替換 字串中指定的字串

需求是將一段內容中的某個特定字串後面新增 一些字串 最好是用到正則替換 preg_match_all('/(http:\/\/blog.com).*?(php)/is',"aaaahttp://blog.com/sss/index.phpsdsdahttp://blog

C# 校驗

regex bool ring false ret case a-z ase stat 郵箱驗證 /// <summary>/// 是否郵箱/// </summary>/// <param name="value">郵箱地址</pa

vim 替換【轉】

rom 使用 tro 所有 table 大小寫 指定 onf lag :[range]s/from/to/[flags] range:搜索範圍,如果沒有指定範圍,則作用於但前行。 :1,10s/from/to/ 表示在第1到第10行(包含第1,第10行)之間搜索替換;

括號替換

mat 北京 blog result () log function true highlight $str="你好<我>(愛)[北京]{天安門}"; echo f1($str); //返回你好 echo f2($str); //返回我 echo f3($st

Javascript與C#中使用表達式

ttr ssi color 指定 att attr http 返回 size JavaScript RegExp 對象 新建一個RegExp對象 new RegExp(pattern,[attributes]) 參數 參數 pattern 是一個字符串,指定

C#中的表達式

常用函數 [0 regex 表達式 matches mat () match split() 常用表達式       ^:  表示字符串的開頭   $:  表示字符串的結尾   .:   匹配除了\n之外的任意單個字符   []:  字符的篩選       []內的內容只