在Linux中,很多应用程序都需要对正则表达式的支持(如:grep,sed,awk等)。所以提供有POSIX式regex支持:
#include <sys/types.h>
#include <regex.h>
suitable for subsequent regexec() searches. */
int regcomp(regex_t *preg, const char *regex, int cflags);
如果是正确的正则式返回0
piled pattern buffer */
int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags);
成功匹配返回0,pmatch[0].rm_so,pmatch[0].rm_eo分别是第一个匹配串在string中的始终位置(-1表示没有匹配的)。
注意:这里pmatch[i](i=1,2,...)不是表示第二,三…个匹配,而是第一个匹配串中的子匹配。如果要找之后的匹配应该从第一个匹配的终位置开始在string中再次regexec()
void regfree(regex_t *preg);
用完正则表达式后,或者要使用新的正则表达式的时候,我们可以用这个函数清空preg指向的regex_t结构体的内容,请记住,如果是使用新的正则表达式,一定要先清空regex_t结构体。
size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size);
返回regcomp/regexec的错误信息,其中errcode是regcomp/regexec的返回,errbuf是最后得到的错误信息。
使用:
先用regcomp()初始化正则式,然后用regexec()查找匹配串,最后别忘了用regfree()清除正则式。
有错误的话用regerror()来获取错误信息。例:#include <stdio.h>
//EOF
Read More...
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <regex.h>
#define SUBSLEN 10
#define EBUFLEN 128 /* error buffer length */
#define BUFLEN 1024 /* matched buffer length */
int
main (int argc, char **argv)
{
FILE *fp;
size_t len=0; /* store error message length */
regex_t re; /* store compilned regular expression */
regmatch_t subs[SUBSLEN]; /* store matched string position */
char matched[BUFLEN]; /* store matched strings */
char errbuf[EBUFLEN]; /* store error message */
int err, i;
char string[] = "AAaba(125){3a}babAbAbCdCd123123 11(923){82}aslfk(72){4}";
char pattern[] = "(\\([0-9]+\\))(\\{[0-9]+\\}{1})";
/*注意: 对于C/C++的正则式,这里要注意的是‘\’字符,因为C中‘\’是转义符,正则式中‘\’也是转义符,所以要匹配的信息中有‘\’时,C的正则式中就要用“\\\\”(C字符串“\\\\”=>正则式“\\”=>字符“\”)
*/
printf ("String: %s\n", string);
printf ("Pattern: \"%s\"\n", pattern);
/* compile regular expression */
err = regcomp (&re, pattern, REG_EXTENDED);
if (err) {
len = regerror (err, &re, errbuf, sizeof(errbuf));
fprintf (stderr, "error: regcomp: %s\n", errbuf);
return (1);
}
printf ("Total has subexpression: %d\n", re.re_nsub);
int offset = 0;
while (1) {
/* execute pattern match */
err = regexec (&re, string+offset, (size_t)SUBSLEN, subs, 0);
if (err == REG_NOMATCH) {
fprintf (stderr, "Sorry, no match ...\n");
regfree (&re);
return (0);
} else if (err) {
len = regerror (err, &re, errbuf, sizeof (errbuf));
fprintf (stderr, "error: regexec: %s\n", errbuf);
return (1);
}
/* if no REG_NOMATCH and no error, then pattern matched */
printf ("\nOK, has matched ...\n\n");
for (i=0; i<=re.re_nsub; i++) {
if (i==0) {
printf ("begin: %d, end: %d, ", subs[i].rm_so, subs[i].rm_eo);
} else {
printf ("subexpression %d begin: %d, end: %d, ", i, subs[i].rm_so, subs[i].rm_eo);
}
len = (int)subs[i].rm_eo - (int)subs[i].rm_so;
memcpy (matched, string + offset + subs[i].rm_so, len);
matched[len] = '\0';
printf ("match: %s\n", matched);
}
offset += (int)subs[0].rm_eo;
} /* while (1) */
regfree (&re);
return 0;
}
2007-01-21
regex in Linux with C
Posted by
Davy Hawk
at
1/21/2007 02:40:00 PM
0
comments
some messages echo
昨天看LFS启动脚本时想到的。
Linux启动时会在每一行信息后都输出一个"[ OK ]"、"[ WARN ]"或"[ FAIL ]",这种输出方式在LFS启动脚本的function中可以得到解答:#!/bin/bash
# output just like linux-bootup message ".... [ OK ]"
## Screen Dimensions
# Find current screen size
if [ -z "${COLUMNS}" ]; then
COLUMNS=$(stty size)
COLUMNS=${COLUMNS##* }
fi
# When using remote connections, such as a serial port, stty size returns 0
if [ "${COLUMNS}" = "0" ]; then
COLUMNS=80
fi
## Measurements for positioning result messages
COL=$((${COLUMNS} - 8))
WCOL=$((${COL} - 2))
## Set Cursor Position Commands, used via echo -e
SET_COL="\\033[${COL}G" # at the $COL char
SET_WCOL="\\033[${WCOL}G" # at the $WCOL char
CURS_UP="\\033[1A\\033[0G" # Up one line, at the 0'th char
## Set color commands, used via echo -e
# Please consult `man console_codes for more information
# under the "ECMA-48 Set Graphics Rendition" section
#
# Warning: when switching from a 8bit to a 9bit font,
# the linux console will reinterpret the bold (1;) to
# the top 256 glyphs of the 9bit font. This does
# not affect framebuffer consoles
NORMAL="\\033[0;39m" # Standard console grey
SUCCESS="\\033[1;32m" # Success is green
WARNING="\\033[1;33m" # Warnings are yellow
FAILURE="\\033[1;31m" # Failures are red
INFO="\\033[1;36m" # Information is light cyan
BRACKET="\\033[1;34m" # Brackets are blue
STRING_LENGTH="0" # the length of the current message
echo -n -e "test test test .............. 11111"
echo -n " ||| now the fkjsal;kfa"
echo -e "${SET_COL}""${BRACKET}""[""${SUCCESS}"" OK ""${BRACKET}""]""${NORMAL}"
echo -n -e "test est esttt esttt ------------ 2222"
echo -e "${SET_COL}""${BRACKET}""[""${FAILURE}"" FAIL ""${BRACKET}""]""${NORMAL}"
echo -n -e "test ewa tasfj a;ksljet;a ljkeakl;j"
echo -e "${SET_COL}""${BRACKET}""[""${WARNING}"" WARN ""${BRACKET}""]""${NORMAL}"
另外,以前看到过的一个旋转的棍子表示进度的,用这种方式:#!/bin/bash
# a rout-line
if [ -z "${COLUMNS}" ]; then
COLUMNS=$(stty size)
COLUMNS=${COLUMNS##* }
fi
if [ "${COLUMNS}" = "0" ]; then
COLUMNS=80
fi
COL=$((${COLUMNS} - 20))
SET_COL="\\033[${COL}G" # at the $COL char
echo -n "asfdl;adfd;jja;:"
let n=0
while test $n -lt 5000 ; do
let n=`expr $n+1` # 这主要还起延时的作用,要不用`let n++`就行了
echo -en "${SET_COL}/"
let n=`expr $n+1`
echo -en "${SET_COL}|"
let n=`expr $n+1`
echo -en "${SET_COL}\\"
let n=`expr $n+1`
echo -en "${SET_COL}-"
done
echo -e "${SET_COL}[ OK ]"
//EOF
Read More...
Posted by
Davy Hawk
at
1/21/2007 12:51:00 PM
0
comments
2007-01-20
LFS单用户模式
今天发现LFS进单用户时会提示:
(or type Control-D to continue)
-_-还要输入密码!?和我平时印象中的单用户不同啊。
虽然在改grub的时候后面加个" init=/bin/bash"也可以进“单用户”。但还是不想这样麻烦。
单用户是[init 1]模式,启动脚本在/etc/rc.d/rc1.d/中,但光看这个目录里的东西是看不出什么的。
这里说一下,LFS的启动脚本和FC6的不同的地方。最大的不同是rcsysinit,LFS中和其他启动级别一样是一个目录的形式以'S'/'K'来判断启动与否(判断模式单一),FC6中是一个rc.sysinit的bash脚本(好处是:模式选则的多样性)
那么大多问题是出在这里,这里不想改动太多就在/etc/rc.d/init.d/中添加一脚本'single',链接之:
single文件内容:
#!/bin/bash
echo "########## Entering Single Mode ##########"
/bin/bash
但注意,/etc/inittab中,需要:
...
l1:S1:wait:/etc/rc.d/init.d/rc 1
...
//EOF Read More...
Posted by
Davy Hawk
at
1/20/2007 12:17:00 PM
0
comments
