正则表达式學習

正則表達式,是用來匹配字符串的一種工具。比如說:要驗證一個電子郵件地址是否合法,要在一個html源文件中找出所有的以<Hn>...</Hn>標識的那部分。還比如在delphi中,我們可以利用支持正則表達式的cxMaskEdit控件來格式化輸入。

一、匹配單個字符
字面匹配
字面匹配就是按原原本本的匹配文字,比如說:
字符串:i have a dream.
正則表達多:rea
那麼被匹配結果是:i have a dream.

任意(任一)匹配
任意匹配就是以含有特定意義的通配符來匹配,就像SQL中的下劃線,它匹配任意一個字符。在正測表達式中,此通配符為半角句點.舉例如下:
字符串:i have a dream.
正則表達式:r.a
那麼被匹配結果是:i have a dream.
說明:如果.匹配任一字符,然只想匹配.本身,方法是在其前面加上右斜線,就如同c語言中的轉義字符,即\.,如前例:
字符串:i have a dream.
正則表達式:\.
那麼被匹配結果是:i have a dream.
像這類的轉意字符還有很多,在後面的部分會有提到。

二、枚舉型匹配
多選一匹配
多選一匹配相當於程序c語言中的枚舉數據類型,它是以方框號來描述的,舉例來說:
字符串:i have a dream,the dream was to be a doctor.
正則表達式:t[hbr]e
那麼匹配結果是:i have a dream,the dream was to be a doctor.

多選一匹配的區間表示
舉例來說:
字符串:
mydoc1.doc
mydoc2.doc
mysheet1.xls
file5.txt
正則表達式:[a-z]c[1-9]\.
那麼匹配結果是:
mydoc1.doc
mydoc2.doc
mysheet1.xls
file5.txt

"Anything But"匹配
意思是除...之外,就是說匹配除了指定字符之外的匹配,表示方法是在表式前加上^,舉例來說:
字符串:
apac1.xls
europe2.xls
sam.xls
正則表達式:[ns]a[^0-9]\.xls
那麼匹配結果是:
europe2.xls
sam.xls
na1.xls


三、元字符
元字符,就是在正則表達式中,用於描述字符的字符,如前面的.,它代表任意一個字符。
再舉例說,前面講到的方括號用於描述枚舉型匹配,那麼如果要表示方括號本身,就需要在其前面加上右斜線,如:
字符串:
var myArray = new Array();
...
if (myArray[0] == 0) {
...
}
正則表達式:myArray\[0\]
匹配結果:
var myArray = new Array();
....
if (myArray[0] == 0) {
...
}

下表列出幾個比較常見的元字符
--------------------
[\b] 退格符
\n 換行符
\r 回車符
\t Tab
\d 數字(等價於[0-9])
\D 非數字(等價於[^0-9])
\w 字母(等價於[a-zA-Z0-9_])
\W 非字母(等價於[^a-zA-Z0-9_])
\s 任意空白字符(等價於[\f\n\r\t\v])
\S 任意非空白字符(等價於[^\f\n\r\t\v])
-----------------------

四、重復匹配
重復匹配就是指匹配多次,下面舉例說明一個多次匹配的例子這個例子匹配文本中所有的電郵地址:
文本:
Send personal email to ben@forta.com. For questions about a book use support@forta.com. Feel free to send unsolicited email to spam@forta.com (wouldn't it be nice if it were that simple, huh?).
正剛表達式:
\w+@\w+\.\w+
匹配結果:
Send personal email to ben@forta.com. For questions about a book use support@forta.com. Feel free to send unsolicited email to spam@forta.com (wouldn't it be nice if it were that simple, huh?).

說明:上面的正則表達式中,+代表其前置內容可重復一或多遍。
與+類似的還有*和?,*代表其前置內容可重復零或多遍,?代表其前置內容可重復零或一遍。

指定重復次數的重復匹配
若要指定重復次數,語法為{n},舉例說明:
文本:
<BODY BGCOLOR="#336633" TEXT="#FFFFFF"
MARGINWIDTH="0" MARGINHEIGHT="0"
TOPMARGIN="0" LEFTMARGIN="0">
正則表達式:
#[\d]{6}
匹配結果:
<BODY BGCOLOR="#336633" TEXT="#FFFFFF"
MARGINWIDTH="0" MARGINHEIGHT="0"
TOPMARGIN="0" LEFTMARGIN="0">


指定重復次數區間的重復匹配
語法為{n,m}{n,},舉例說明:
文本:
/8/03
10-6-2004
2/2/2
01-01-01
正則表達式:
\d{1,2}[-\/]\d{1,2}[-\/]\d{2,4}
匹配結果:
/8/03
10-6-2004
2/2/2
01-01-01

幾個等價的語法標識
--------------
* *?
+ +?
{n,} {n,}?
--------------

五、起止符
單詞起止
看下面這個例子。
文本:
The cat scattered his food all over the room.
正則表達式:
cat
匹配結果:
The cat scattered his food all over the room.

再看下面這個例子。
文本:
The cat scattered his food all over the room.
正則表達式:
\bcat\b
匹配結果:
The cat scattered his food all over the room.

對比以上兩個例子,我們可以看出來\b是一個起止符,表示其前或其後沒有其它非空字符,相當於匹配一個完整的單詞。

再看兩個例子,加深對\b的理解。
文本:
The captain wore his cap and cape proudly as he sat listening to the recap of how his crew saved the men from a capsized vessel.
正則表達式:
\bcat
匹配結果:
The captain wore his cap and cape proudly as he sat listening to the recap of how his crew saved the men from a capsized vessel.

文本:
The captain wore his cap and cape proudly as he sat listening to the recap of how his crew saved the men from a capsized vessel.
正則表達式:
cat\b
匹配結果:
The captain wore his cap and cape proudly as he sat listening to the recap of how his crew saved the men from a capsized vessel.

行起止
如果說想要匹配jave語言代碼一整行單行的注釋,可以參考下面這個例子。
文本:
function doSpellCheck(form, field) {
// Make sure not empty
if (field.value == '') {
return false;
}
// Init
var windowName='spellWindow';
var spellCheckURL='spell.cfm?formname=comment&fieldname='+field.name;
...
// Done
return false;
}
正則表達式:
^\s*//[\n\r]*$
匹配結果:
function doSpellCheck(form, field) {
// Make sure not empty
if (field.value == '') {
return false;
}
// Init
var windowName='spellWindow';
var spellCheckURL='spell.cfm?formname=comment&fieldname='+field.name;
...
// Done
return false;
}
說明:
如前所講,元字符^如果出現在[]中,表示否定,否則表示從行的起始;
元字符$表示至行的結束。

六、SubExpression
SubExpression是子表達式的意思,將正則表達式分層,一個表達式中可以包含子表達式,SubExpression用圓括號()來分隔,()內的表達式作為一個個體來對待,考慮下面這個例子。
文本:
Hello, my name is Ben Forta, and I am the author of books on SQL, ColdFusion, WAP,Windows  2000, and other subjects.
正則表達式:
 {2}
匹配結果:
Hello, my name is Ben Forta, and I am the author of books on SQL, ColdFusion, WAP,Windows  2000, and other subjects.

說明:為什麼會沒匹配到呢?因為{2}只修飾其前一個描述符,也就是;,所以這樣是匹配不到的。但是如果正則表達式是:
( ){2}
則匹配結果為:
Hello, my name is Ben Forta, and I am the author of books on SQL, ColdFusion, WAP,Windows  2000, and other subjects.

子表達式的嵌套與枚舉
SubExpression是可以嵌套的,看下面這個例子。
假設我們要匹配一段文字中的考試成績,這個成績是百分制的數字,小數位最多只有一位,且必須是0.5,假設文本如下:
小明的考試成績是95.5,小華的考試成績是100,小劉的成績是32,小張的成績是76.3。
正則表達式:
((0|[1-9][\d])(\.5))|(0|[1-9][\d])|100
那麼匹配結果是:
小明的考試成績是95.5,小華的考試成績是100,小劉的成績是32,小張的成績是76.3。

說明:多外並列的多選一的subexpression之間用|隔開,表示或者的意思。


七、前引匹配
請看下面這個例子。
文本:
<H2>Wireless</H2>
Information about Bluetooth, 802.11, and more.
<H2>This is not valid HTML</H3>
正則表達式:
<[hH][1-6]>.*?</[hH][1-6]>
匹配結果:
<H2>Wireless</H2>
Information about Bluetooth, 802.11, and more.
<H2>This is not valid HTML</H3>

很明顯,顯後一行<H2>This is not valid HTML</H3>的匹配結果不是我們想要的,因為它是以<H2>開頭卻以</H3>結尾。
那麼如果要做這一點,正則表達式該如何寫呢?
可以這樣寫:
<[hH]([1-6])>.*?</[hH]\1>
那麼這樣的話,上述例子的匹配結果就是:
<H2>Wireless</H2>
Information about Bluetooth, 802.11, and more.
<H2>This is not valid HTML</H3>

說明:\1表示參照引用前面表達式中的第一個subexpression,如果是\2,就表示參照引用前面表達式中的第二個subexpression.可以看出上述例子中\1參照引用了([1-6]),這個“參照引用”含有一個順序一致的意思,就是說,如果([1-6])匹配的是1,那麼這裡也只能匹配1,如果([1-6])匹配的是2,這裡也只能匹配2。

八、頭尾條件匹配
舉例說文本:
<title>some words</title>
我只想要匹配以<title>開始,並以</title>結束的內容,但匹配的結果不要包含<title>和</title>本身。那麼,正則表達式可以這樣寫:
(?<=<title>).*(?=</title>)
這樣的話匹配結果就是:
<title>some words</title>

說明:?<=後跟著的是匹配的結果的前置內容,?=跟著的是匹配結果的後置內容。而且,如果前置或後置內容是多個字符的話,請用()將其包起來。

相反的情況
好,那麼我們很自然的會想到,我要匹配不以<title>和</title>為起始的內容。這時,用另外兩個語法符號:
(?!)和(?<!)
如下例。
文本:
<title>some words</title>
<body>some words</body>
正則表達式:
(?<!<title>).*(?!</title>)
匹配結果如下:
<title>some words</title>
<body>some words</body>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值