php正则表达式实例详解,正则表达式实例解析
正則表達(dá)式實(shí)例解析
類別: 技術(shù)
時(shí)間:2016-06-02 10:14:14
字?jǐn)?shù):6253
版權(quán)所有,未經(jīng)允許,請(qǐng)勿轉(zhuǎn)載,謝謝合作~
### 前言
正則表達(dá)式(regular expression)幾乎在所有主流計(jì)算機(jī)語(yǔ)言中都有涉及,初學(xué)者很多時(shí)候都是從某些地方copy過來,如果不了解它,那也不知道copy的東西對(duì)不對(duì)。
它并不是一門語(yǔ)言,而是對(duì)字符串操作的一種邏輯公式,常常用regex表示。有趣的是,正則表達(dá)式并非計(jì)算機(jī)首創(chuàng),而是源于數(shù)學(xué)科學(xué)家Stephen Kleene的《神經(jīng)網(wǎng)事件的表示法》論文中, 再被引入U(xiǎn)nix工具軟件,自此廣泛被利用,驗(yàn)證了理論先于實(shí)踐。雖然不同的語(yǔ)言上會(huì)有一些流派的小差異,思想?yún)s是相同,為了方便表述,本處多以JavaScript為例。
正則就像翻譯一樣,同樣的意思,有不同的翻譯法,不同的高度。
PS:講個(gè)小故事,有人以為只要英語(yǔ)足夠牛逼,就可以成為牛逼的翻譯官,too young too simple。電影《降臨》七肢桶提供表意“武器”,這個(gè)可以翻譯成知識(shí),也可以成兵器,差別極大。比起外語(yǔ)能力,更重要的是知識(shí)深度與良知正義,所以翻譯官就像語(yǔ)言學(xué)家一樣,永無止境的東西。
正則表達(dá)式無非是實(shí)現(xiàn)兩個(gè)功能,搜索與替換。博客內(nèi)容來自[西法](http://www.boatsky.com "太空船博客" rel="nofollow")之前寫的靜態(tài)頁(yè),附帶表達(dá)式工具:https://www.boatsky.com/static/tools/regexp/regexp.html
### 常用語(yǔ)法
^字符串開始位置
$字符串結(jié)束位置
\轉(zhuǎn)義字符
\d數(shù)字
\D非數(shù)字
\w任何單詞字符,包括字母數(shù)字下劃線
\W非單詞字符
\s不可見字符
\S可見字符
+匹配表達(dá)式1次以上
星號(hào),匹配表達(dá)式任意次,盡量使用*?這種非貪婪的模式
?匹配表達(dá)式1次或0次
{n}匹配表達(dá)式n次,n非負(fù)
{n,m}匹配表達(dá)式n次至m次,n<=m
[abcde]匹配字符集任意一個(gè),等價(jià)于[a-e]
[^0-9]匹配不在本字符集任意一個(gè),等價(jià)于\D
(x|y|z)匹配字符集任意一個(gè),等價(jià)于[xyz]
\b 單詞邊界
\B 非單詞邊界
以下為非獲取匹配子表達(dá)式
(?:pattern) 匹配pattern但不獲取匹配結(jié)果,不進(jìn)行存儲(chǔ)供以后使用
(?=pattern) 正向肯定預(yù)查
(?!pattern) 正向否定預(yù)查
(?<=pattern) 反向肯定預(yù)查
(?
### 簡(jiǎn)單實(shí)例
#### QQ號(hào)
分析:QQ號(hào)是純數(shù)字,4位至10位,不過也有把11位手機(jī)號(hào)當(dāng)QQ的情況
正則:
```
/^[1-9]\d{3,10}$/
```
#### 手機(jī)號(hào)碼
分析:
移動(dòng)號(hào)19:134,135,136,137,138,139,147,150,151,152,157,158,159,178,182,183,184,187,188
聯(lián)通號(hào)09:130,131,132,155,156,185,186,145,170,171,176
電信號(hào)06:133,153,177,180,181,189
綜合:
130,131,132,133,134,135,136,137,138,139
145,147
150,151,152,153,155,156,157,158,159
170,171,176,177,178
180,181,182,183,184,185,186,187,188,189
正則:
```
/^(13|14|15|17|18)[0-9]{9}$/
```
#### 數(shù)字
js中,如果想驗(yàn)證整數(shù)n,可以直接用Number.isInteger(n)。
如果要驗(yàn)證n是否是數(shù)字,我們一般是使用:
Object.prototype.toString.call(n) === '[object Number]'
這存在幾個(gè)明顯的問題:
其一:如果n是一個(gè)數(shù)字,傳輸中是以String來傳的,這時(shí)有問題
其二:如果n為NaN,也認(rèn)為是數(shù)字,這可能不是我們想要的
其三:JS數(shù)字范圍有限,如果超過了JS數(shù)字的范圍1.797693134862316e+308,n變成了Infinity,這時(shí)上式也成立,我們并不想認(rèn)為Infinity是數(shù)字。
其四:我們可能只想要一個(gè)驗(yàn)證長(zhǎng)是不是數(shù)字,比如有個(gè)極大的數(shù),超出了JS數(shù)的范圍,不應(yīng)該認(rèn)為這個(gè)極大的數(shù)就不是數(shù),只是原生JS不支持而已。
為了解決這些問題,用正則匹配。
我們把數(shù)分成整數(shù)、小數(shù)、指數(shù),其中整數(shù)部分與指數(shù)數(shù)字是帶正負(fù)的
整數(shù) [\+\-]?\d*
小數(shù)部分 \.\d+
指數(shù) e[\+\-]?\d*
最終
```
/^[\+\-]?\d*(\.\d+)?(e[\+\-]?\d*)?$/
```
#### 郵箱
分析:郵箱的格式一直是一個(gè)有爭(zhēng)議的問題,最常見的格式如xx@xx.xx,不過像xx.oo@xx.com.cn,xx_xx-xx+xx.xx@xx-xx.xx也能見到。
不過多數(shù)郵箱還是會(huì)在做出類似以下的限定:
1.郵箱只能包含字母數(shù)字.-_+與一個(gè)@,@之前必須有字母或數(shù)字,@之后必須要"2級(jí)域名"."1級(jí)域名"
2.開頭必須是字母或數(shù)字,不能有連續(xù)的.-_
3.一級(jí)域名一般是只包含字母
正則:
```
/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.[a-zA-Z]+$/
```
#### 網(wǎng)址
分析:網(wǎng)址正則幾乎隨處可見,前綴是傳輸協(xié)議,如http,https,ftp,sftp,rtsp(實(shí)時(shí)流傳輸協(xié)議),mms(串流媒體傳送協(xié)議),magnet(BT種子)等等,接著則是三級(jí)域名(有可能省略),二級(jí)域名,一級(jí)域名,當(dāng)然也可能只是IP址,最后詳細(xì)路徑
本處,以本網(wǎng)為例
正則:
```
/^http(s?):\/\/((\w)+\.)?boatsky\.com(\.cn)?(\/|$)/i
```
#### 日期時(shí)間
分析:日期時(shí)間格式 多樣,為了便于表示,以傳統(tǒng)日期年月日時(shí)分秒,格式xxxx/xx/xx xx:xx:xx為例,其中年份為4位數(shù),所有位數(shù)不足都須補(bǔ)0
首先,我要要驗(yàn)證這個(gè)輸入是否像一個(gè)日期,并不考慮這個(gè)日期是否存在
日期+時(shí)間格式正則:
```
/^\d{4}\/(0[1-9]|1[0-2])\/(0[1-9]|[12][0-9]|3[01])(\x20)(2[0-3]|[0-1][0-9]):([0-5]\d):[0-5]\d$/
```
分析:如果加上1,3,5,7,8,10,12月有31天,4,6,9,11有30天,2月有28天(假設(shè)都是平年)
平年月份的正則:
```
/02\/(0[1-9]|1[0-9]|2[0-8])|(0[469]|11)\/(0[1-9]|[12][0-9]|30)|(0[13578]|1[02])\/(0[1-9]|[12][0-9]|3[01])/
```
所以平年的正則:
```
/^\d{4}\/((02\/(0[1-9]|1[0-9]|2[0-8])|(0[469]|11)\/(0[1-9]|[12][0-9]|30)|(0[13578]|1[02])\/(0[1-9]|[12][0-9]|3[01])))(\x20)(2[0-3]|[0-1][0-9]):([0-5]\d):[0-5]\d$/
```
再加上閏年(能被4整除,若能被100整除則需要再被400整除,就是所謂的“4年一閏,100年不閏,400年再閏”),閏年2月29天,平年2月28天
閏年2月有29天也就是兩種情況:
1.能被4整除且不能被100整除。什么樣的數(shù)能被4整除?因?yàn)?00能被4整除,所以只要保證后兩位數(shù)能被4整除就行了,即“個(gè)位為048,十位為偶數(shù)”或“個(gè)位為26,十位為奇數(shù)”,加上個(gè)位與十位不能同時(shí)為0,如下:
```
/\d{2}([2468][048]|[13579][26]|0[48])/
```
2.能被400整除。千位與百位需要被4整除,(沒有公元0年,只有公元前1年與公元1年)
```
/([2468][048]|[13579][26]|0[48])00/
```
所以閏年的正則:
```
/\d{2}([2468][048]|[13579][26]|0[48])|([2468][048]|[13579][26]|0[48])00/
```
綜上,最終結(jié)果:
```
/^((\d{4}\/((02\/(0[1-9]|1[0-9]|2[0-8])|(0[469]|11)\/(0[1-9]|[12][0-9]|30)|(0[13578]|1[02])\/(0[1-9]|[12][0-9]|3[01]))))|((\d{2}([2468][048]|[13579][26]|0[48])|([2468][048]|[13579][26]|0[48])00)\/(02\/(0[1-9]|1[0-9]|2[0-9])|(0[469]|11)\/(0[1-9]|[12][0-9]|30)|(0[13578]|1[02])\/(0[1-9]|[12][0-9]|3[01]))))(\x20)(2[0-3]|[0-1][0-9]):([0-5]\d):[0-5]\d$/
```
#### 密碼復(fù)雜度
分析:現(xiàn)在很多網(wǎng)站都流行對(duì)用戶的密碼進(jìn)行安全等級(jí)評(píng)定,提醒用戶設(shè)置更復(fù)雜的密碼,更大可能的保護(hù)賬戶安全。
其實(shí)所謂的復(fù)雜度,無非就是用多個(gè)正則進(jìn)行配置,匹配上越多的正則,則復(fù)雜度越高
本處對(duì)密碼設(shè)以下規(guī)則,長(zhǎng)度8-32,建議包括大寫字母,建議包括小寫字母,建議包括數(shù)字,建議包括特殊字符,不建議包括三個(gè)連續(xù)字符,
### JavaScript中簡(jiǎn)單使用
在JS中,正則表達(dá)式用RegExp對(duì)象表示,可以用RegExp(pattern,attributes)構(gòu)造函數(shù)來創(chuàng)建RegExp對(duì)象,其第一個(gè)參數(shù)pattern是上述的正則表示式,第二個(gè)參數(shù)是修飾符,g(全局匹配),i(不區(qū)分大小寫匹配),m(多行匹配)
```javascript
var regExp = new RegExp("/^(13|14|15|17|18)[0-9]{9}$/");
```
也可以特殊的直接量語(yǔ)法創(chuàng)建:
```javascript
var regExp = /^(13|14|15|17|18)[0-9]{9}$/;
```
RegExp包括以下方法:
complie:編譯正則,增快速度
test:檢索字符串指定值
```javascript
var regExp = new RegExp(/^(13|14|15|17|18)[0-9]{9}$/);
var result = regExp.test("18812345678"); //返回true或false,這里是true
```
exec:檢索字符串指定值,并確定位置,如果搜索修飾符不是g,那么返回值第0個(gè)是匹配上的字符串還包括index(匹配文本第一個(gè)的位置)與input(當(dāng)前被匹配的字符串)兩個(gè)屬性
```javascript
var regExp = new RegExp(regExpValuePattern);
var checkResult = regExp.exec(checkContentValue);
if(checkResult){
printResult = "位置:" + checkResult.index + ",字符:" + checkResult[0];
}
var regExp = new RegExp(/a/,g);
var result;
while((result == regExp.exec("abcdefabdaafg"))){
console.log(result);
console.log(regExp.lastIndex);
}
```
String對(duì)象有search,match,replace,split是支持正則表達(dá)式的
比如用replace把一個(gè)正整數(shù)轉(zhuǎn)成千位用,分隔
```javascript
function numberFormat(num) {
if(!(Object.prototype.toString.call(1) === '[object Number]' && Math.floor(num) === num)){
return num;
}
let reg=/\d{1,3}(?=(\d{3})+$)/g;
return (num + '').replace(reg, '$&,');
}
```
### PHP中簡(jiǎn)單使用
如果懶的裝PHP,則可以使用在線的PHP編譯方式:
或
preg_match("$regex",$byMatchStr),其中$regex為正則表達(dá)式,$byMatchStr為被匹配的字符串,成功返回true,否則false:
```php
if(preg_match("/php/", "php is best language of the world. php is not pai huang pian.", $matches)){
echo "php was found:". $matches[0];
} else {
echo "php was not found:";
}
```
preg_match_all("$regex",$byMatchStr),其中$regex為正則表達(dá)式,$byMatchStr為被匹配的字符串,成功返回true,否則false:
```php
if(preg_match_all("/php/", "php is best language of the world. php is not pai huang pian.", $matches)){
echo "php was found:"
var_dump($matches); } else {
echo "php was not found:";
}
```
preg_replace("$regex",$str,$byMatchStr),其中$str把$byMatchStr替換掉的字符串:
```php
$byMatchStr = "php is best language of the world.";
echo $byMatchStr;
echo "\n";
echo preg_replace("/php/","JavaScript",$byMatchStr);
echo "\n";
echo $byMatchStr;
```
preg_split("$regex",$byMatchStr),使用正則轉(zhuǎn)換數(shù)組:
```php
$byMatchStr = "php is best language of the world.";
$array = preg_split("/ /",$byMatchStr);
foreach($array as $a){
echo $a."\n";
}
```
preg_grep("$regex",$byMatchArray),使用正則替換數(shù)組,生成新數(shù)組:
```php
$byMatchArray = array("a","b","c","ab","ba","bc");
$newArray = preg_grep("/b$/",$byMatchArray);
var_dump($newArray);
```
全部留言
我要留言
內(nèi)容:
網(wǎng)名:
郵箱:
個(gè)人網(wǎng)站:
發(fā)表
總結(jié)
以上是生活随笔為你收集整理的php正则表达式实例详解,正则表达式实例解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python搭建django框架,Pyt
- 下一篇: html php 混编 H1,在一个HT