2007年11月28日星期三

lex/yacc系列:正则表达式

正则表达式是一种使用“元(meta)”语言的模式描述,元语言用于描述特定模式。

.匹配除换行符(“\n”)之外的任意单个字符
*匹配前述表达式的零个或多个拷贝
+匹配前述表达式的一个或多个拷贝
?匹配前述表达式的零个或一个拷贝
^表示表达式的第一个字符匹配行首。也用于方括号中的否定。
$表示表达式的最后一个字符匹配行尾,“r$”等同于“r/\n”
\用于转义元字符,并且作为通常C转义序列的一部分,例如,“\n”是换行符,“\*”是星号,“\0”是空字符,“\123”表示8进制数123,“\x2a”表示16进制数2a。
[]匹配括号中任意字符的字符集。如果第一个字符是“^”,含义改变为匹配除括号中的字符以外的任意字符。方括号中的“-”表示一个字符范围,例如,“[0-9]”和“[0123456789]”的含义相同。“¦”或“]”作为“[”后的第一个字符时按字面意思解释,即短划线或方括号。
{}如果括号中包含一个或两个数字,指示前述表达式被允许匹配的次数,例如,A{1,3}表示匹配字母A一次到三次,A{2,}表示匹配字母A两次或以上,A{4}则表示匹配字母A四次。如果包含名称,则表示以该名称作替换。
¦表示“或者”,匹配其中的一个表达式
""字面引述
/只在斜线后面跟有指定的正则表达式时才匹配斜线之前的正则表达式。例如,0/1匹配字符串“01”中的“0”,但是不匹配“0”或“02”中的任何字符。由斜线后的模式所匹配的内容并不被“使用”,会被转变为随后的标记。一个模式中只允许使用一个斜线。
()将一系列正则表达式组成一个新的正则表达式

例1:
表达一个数字:
[0-9]
表示整数的正则表达式:
[0-9]+
上面的表达式要求至少有一个数字。下面的允许没有数字:
[0-9]*
添加一个可选的负数符号:
-?[0-9]+
扩展到表示小数(要求最后一位必须是数字):
[0-9]*\.[0-9]+
注意上述表达式中小数点“.”之前的“\”,使得它只能匹配小数点,而不是任意一个字符。而且这个表达式不能匹配整数。不考虑负号,合并匹配:
([0-9]+)([0-9]*\.[0-9]+)
上述表达式中使用括号“()”分组。加入负号:
-?(([0-9]+)([0-9]*\.[0-9]+))
进一步扩展,允许浮点风格的指数。先定义指数的正则表达式:
[eE][-+]?[0-9]+
表达式允许大写或者小写的字母E,然后是可选的正号或负号,以及一个整数。下面把它们组合在一起,表达一个实数的正则表达式:
-?(([0-9]+)([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?)
其中的指数部分是可选的。

例2:另一个用于脚本和简单的配置文件常见的正则表达式,匹配以“#”开始的注释:
#.*

例3:下面是匹配引用字符串的正则表达式:
\"[^"\n]*["\n]

没有评论: