摘要:字符組字符組就是一組字符,在正則表達式中,它表示在同一個位置可能出現的各種字符。放在正則表達式的開頭,表示定位到字符串的起始位置用在正則表達式的末尾,表示定位到字符串的結束位置。
這里的知識點基本上是《正則指引》的讀書筆記,只是每個知識點的示例代碼用php來實現。
1. 字符組字符組的基本用法字符組(Character Class)就是一組字符,在正則表達式中,它表示“在同一個位置可能出現的各種字符”。
寫法:[ab]、[314]、[#.?]
[...]
preg_match("/[0123456]/", "5"); // => 1 preg_match("/[abc123]/", "5"); // => 0范圍表示法(range)
[x-y]表示x到y整個范圍內的字符。如,[0123456789]表示為[0-9],[abcdefghijk]表示為[a-k]。
為什么是[0-9],而不是[9-0]?
因為-表示的范圍一般是根據字符對應的碼值(Code Point)來確定的。典型地有ACSⅡ編碼。在ACSⅡ編碼中,0~9的碼值是48~57,a~z的碼值是97~122,A~Z的碼值是65~90。
preg_match("/[0-9]/", "5"); // => 1 preg_match("/[a-z]/", "5"); // => 0 preg_match("/[0-9a-fA-F]/", "0"); // 16進制字符組簡記法(shorthands)
提供比范圍表示法更簡潔的表示方法,如d表示[0-9],w表示[0-9a-zA-z_]。
php中支持的字符組簡記:
d 所有的數字,即[0-9]
D 所有的非數字,與d互斥
w 所有的單詞字符(字符、數字、下劃線),即[0-9a-zA-Z_]
W 所有的非單詞字符,與W互斥
s 所有的空白字符,包括空格、制表符、回車符、換行符等空白字符
S 所有的非空白字符,與s互斥
preg_match("/d/", "8"); // => 1 preg_match("/d/", "a"); // => 0 preg_match("/d[a-z]/", "a"); // => 1 preg_match("/w/", "a"); // => 1 preg_match("/w/", "6"); // => 1 preg_match("/w/", "_"); // => 1 preg_match("/s/", " "); // => 1 preg_match("/s/", " "); // => 1 preg_match("/s/", " "); // => 1元字符與轉義
在范圍表示法中,字符組中的橫線-不能匹配橫線字符,而是用來表示范圍,這類字符叫做元字符(meta-character)。元字符除了-還有開方括號[、閉剛括號]、^、$等,它們都有特殊的意義。
當元字符想要表示普通字符的含義時(如-就只想表示橫線字符),就需要轉義處理(在元字符前加反斜線字符)。對于-,有一個例外情況,就是當它緊跟著字符組中的開括號[時,它就表示普通橫線字符,此時不用轉義。
preg_match("/[0-9]/", "-"); // => 1 preg_match("/[0-9]/", "8"); // => 0 preg_match("/[0-9]/", "0"); // => 1 preg_match("/[-09]/", "-"); // => 1 preg_match("/[0-9]/", "-"); // => 1 preg_match("/[0-9]/", "-"); // => 1
仔細看上面第一個表達式和最后兩個表示式。這里要注意:
在php中,字符串既可以用單引號標注也可以用雙引號標注。兩者的主要區別在于,雙引號字符串可以插值,二單引號字符串不能;另外,雙引號字符串會處理字符串轉義,二單引號字符串不會
正則表達式是以字符串的方式提供的。在php中,雙引號字符串本身也有關于轉義的規定(如""、" "、" "等),因此"0-9"與"0-9"是等價的。
那么最后一個表達式為什么也可以匹配呢?這是因為,盡管php的正則表達式用字符串文字給出,但它與常見的字符串不完全一樣——如果某個轉義序列可以有字符串識別,則對其進行轉義處理;否則,將整個轉義序列“原封不動”地保存下來。
因此,在正則表達式中轉義要小心,在php中,使用單引號字符串來構建正則表達式會比雙引號字符串更簡單明了。
排除型字符組(Negated Character Class)在方括號[…]中列出希望匹配的所有字符叫做“普通字符組”。在開方括號[之后緊跟一個脫字符^,寫作[^…],表示“在當前位置,匹配一個沒有列出的字符”。例如,[^0-9]匹配非數字字符。
preg_match("/[^0-9][0-9]/", "A8"); // => 1
排除型字符組中的緊跟著開方括號[的脫字符^也是元字符,如果要匹配尖括號字符,需要進行轉義處理。但是,不緊跟著開方括號[的^就是普通字符,不需要轉義。
preg_match("/[^0-9]/", "0"); // => 0 preg_match("/[^0-9]/", "0"); // => 1 preg_match("/[^0-9]/", "^"); // => 1 preg_match("/[0-9^]/", "^"); // => 1POSIX字符組
之前介紹的字符組,都屬于Perl衍生出來的正則表達式流派(Flavor),這個流派叫做PCRE(Per Compatible Regular Expression)。正則表達式還有其他流派,比如POSIX(Portable Operating System Interface for unix),它是一系列規范,定義了UNIX操作系統應當支持的功能,其中也包括了正則表達式的規范。
常見的[a-z]形式的字符組,在POSIX規范中仍然獲得支持,稱作POSIX方括號表達式。POSIX方括號表達式中的不是用來轉義的,如[d]就只能匹配和d兩個字符。這里涉及到]、-這兩個特殊字符,在POSIX規范中,緊接在開方括號[之后的]才表示閉方括號字符,緊挨在閉方括號]之前的-才表示橫線字符。
對于PCRE規范中的d、w、s等字符組簡記法,POSIX中有類似的東西,叫做POSIX字符組。在ASCⅡ語言環境(locale)中,常見的POSIX字符組及其含義如下:
POSIX字符組 | 說明 | ACSⅡ字符組 | 等價的PCRE簡記法 |
---|---|---|---|
[:alnum:] | 字母和數字 | [0-9a-zA-Z] | |
[:alpha:] | 字母 | [a-zA-Z] | |
[:ASCⅡ] | ASCⅡ字符 | [x00-x7F] | |
[:blank:] | 空格字符和制表字符 | [ ] | |
[:cntrl:] | 控制字符 | [x00-x1Fx7F] | |
[:digit:] | 數字字符 | [0-9] | d |
[:graph:] | 空白字符之外的字符 | [x21-x7E] | |
[:lower:] | 小寫字母字符 | [a-z] | |
[:print:] | 類似[:graph:],但包括空白字符 | [x20-x7E] | |
[:punct:] | 標點符號 | [][!"#$%&"()*+,./:;<=>?@^_`{ | }~-] |
[:space:] | 空白字符 | [ vf] | s |
[:upper:] | 大寫字母 | [A-Z] | |
[:word:] | 字母字符 | [A-Za-z0-9_] | w |
[:xdigit:] | 十六進制字符 | [A-Fa-f0-9] |
php中有專門處理POSIX正則的函數,但從5.3.0開始已經廢棄了。這里只是了解一下相關知識。
2. 量詞這里首先介紹一下^和$兩個特殊字符,在上一章的元字符與轉義一節提到過這兩個特殊字符。
^放在正則表達式的開頭,表示“定位到字符串的起始位置”;$用在正則表達式的末尾,表示“定位到字符串的結束位置”。
preg_match("/wd/", "1a2b"); // => 1 preg_match("/^wd/", "1a2b"); // => 0 必須以字母開頭 preg_match("/wd$/", "1a2b"); // => 0 必須以數字結尾 preg_match("/^wd/", "a2b"); // => 1 preg_match("/wd$/", "1a2"); // => 1 preg_match("/^wd$/", "1a2"); // => 0 開頭必須是字母,結尾必須是數字 preg_match("/^wd$/", "a2"); // => 1量詞的一般形式
如果要匹配一個郵政編碼(6位數字),目前能寫出來的正則表達式是^ffffdffffd$:
preg_match("/^ffffdffffd$/", "100010"); // => 1 preg_match("/^ffffdffffd$/", "10001035"); // => 0 preg_match("/^ffffdffffd$/", "10a010"); // => 0
d重復6次的寫法很不科學,正則表達式肯定會有更方便的寫法,也就是量詞(quantifier)。量詞的通用形式是{m,n}(注意,,后面不能有空格),它限定之前的元素能夠出現的次數,m是下限,n是上限。其他常見的量詞形式有:
量詞 | 說明 |
---|---|
{n} | 之前的元素必須出現n次 |
{m,n} | 之前的元素最少出現m次,最多出現n次 |
{m,} | 之前的元素最少出現m次,出現次數無上限 |
{0,n} | 之前的元素可以不出現,也可以出現,最多出現n次 |
preg_match("/^d{6}$/", "100010"); // => 1 preg_match("/^d{4,6}$/", "123"); // => 0 preg_match("/^d{4,6}$/", "1234"); // => 1 preg_match("/^d{4,6}$/", "123456"); // => 1 preg_match("/^d{4,6}$/", "1234567"); // => 0常用量詞
正則表達式還有三個常用的量詞,分別是+、?、*:
常用量詞 | {m,n}等價形式 | 說明 |
---|---|---|
* | {0,} | 可能出現,也可能不出現,出現次數沒有上限 |
+ | {1,} | 至少出現1次,出現次數沒有上限 |
? | {0,1} | 出現0次或1次 |
這三種量詞在實際中使用的非常多。
例如,匹配url的時候,有可能是http,也有可能是https,這個時候用?就很方便:
preg_match("/^https?://www.baidu.com/", "http://www.baidu.com"); // => 1 preg_match("/^https?://www.baidu.com/", "https://www.baidu.com"); // => 1
在匹配html的tag(如、 <(?!/).*+(? 上面的正則表達式中有兩個環視結構,一個在開尖括號<之后,表示在尖括號<后向右看看,右邊的第一個字符不能為/(正則表達式中進行了轉義);另外一個在閉尖括號>之前,表示在閉尖括號>之前向左看看,左邊挨著的字符不能為/。 上面的正則表達式已經解決了匹配html中開標簽的主要問題,只是其中的.*?還需要優化一下。需要解決的問題是: 有可能會有單引號"或雙引號",它們都得成對出現 單引號對或雙引號對之內可以有>字符,但是它們的外面不能有>字符 利用正則表達式的選擇結構,可以寫出下面的表達式,用于完善上面的問題。 <(?!/)(?:"[^"]*"|"[^"]*"|[^"">])+(? 前面的內容中已經出現介過了單行模式、多行模式、非貪婪模式。匹配模式是指匹配時使用的規則。常用的匹配模式還有不區分大小寫模式、注釋模式。 在開始介紹具體的模式之前,先介紹php中模式的兩種具體實現/.../{modifier}和...(?{modifier})...: 在html中是不區分大小寫的,例如 <[tT][dD]> 由于 / 形式:/.../s或...(?s)... 與單行模式沒有關系。影響^和$的匹配 (?#...)的方法可以在正則表達式中添加注釋 更徹底地,可是使用/.../x表示注釋模式 要匹配中文等Unicode字符,最好是指定Unicode模式修飾符/.../u。如果不指定會有兩個問題 GBK編碼環境下,中文不能匹配 無法利用[x{4e00}-x{9fff}]匹配中文 文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。 轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/21135.html 摘要:一正則表達式函數解析表單驗證等地址的合法性匹配結果可以看作是值非法詞的過濾二正則表達式基本語法測試正則表達式的工具中午匹配最好轉成轉換工具注意是必須在一起的,否則如下也被當成一個原子去匹配。
一、PHP正則表達式函數解析
showImg(https://segmentfault.com/img/bVThUH?w=638&h=95);
showImg(https://segmentfau... 摘要:是決定正則表達式匹配規則的主要部分。二分隔符分隔符的選擇當使用函數的時候,正則表達式必須由分隔符閉合包裹。果分隔符經常在正則表達式內出現,最好使用其他分隔符來提高可讀性。需要將一個字符串放入正則表達式中使用時,可以用函數對其進行轉義。
一、簡介
1. 什么是正則表達式
正則表達式(Regular Expression)就是用某種模式去匹配一類字符串的一種公式。正則表達式使用單個字符串來... 摘要:在閱讀這篇文章前最好把同系列文章實戰正則表達式一驗證手機號先仔細閱讀一遍。但實際上這樣一個表達式是無法從上面的中提取第一個元素的這里主要的問題是在默認情況下點號字符無法匹配換行符。但是很遺憾,正則表達式中沒有排除型子表達式或者說排除型分組。
這篇文章通過提取html元素介紹了正則表達式中模式修飾符、貪婪匹配與非貪婪匹配、Unicode模式、環視等知識點。在閱讀這篇文章前最好把同系列文章... 摘要:兼容的正則表達式已經實現了很多使用不同解析引擎的正則函數。中主要有兩個正則解析器一個稱為,另一個稱為兼容正則表達式。在中,每個正則表達式模式都是使用符合格式的字符串。
原文鏈接: Getting Started with PHP Regular Expressions
Last-Modified: 2019年5月10日16:23:19譯者注:
本文是面向0正則基礎的phper, 很多... 閱讀 3729·2021-11-24 09:39 閱讀 2610·2019-08-30 15:54 閱讀 1149·2019-08-30 13:01 閱讀 3429·2019-08-28 18:30 閱讀 1623·2019-08-26 17:44 閱讀 3591·2019-08-26 11:31 閱讀 2413·2019-08-26 10:40 閱讀 1239·2019-08-26 10:27
直接使用<[^/]+>將/字符排除是不對的,因為有些標簽的屬性中可能會含有/字符。例如。這里只是在開尖括號<之后的第一個字符和閉尖括號>之前的第一個字符不能為/。
然而<[^/][^>]*[^/]>也是不行的,因為在<與>之間會至少匹配兩個字符,像這樣的標簽是無法匹配到的。這里就要用到環視了。
不區分大小寫模式
模式修飾符
/.../{modifier}
...(?{modifier})...
示例
/
.* /s(?s).*
名稱(php手冊)
模式修飾符
模式內修飾符
名稱(《正則指引》)
預定義常量
模式修飾符
作用范圍
整個正則表達式
不在分組(子表達式)中時,對它后面的全部正則表達式起作用;如果在分組(子表達式)中,則對它分組中的剩余部分起作用。在沒有分組,且放在整個正則表達式最前面的時候相當于/.../{modifier}
支持程度
支持所有模式修飾符
支持部分模式修飾符
其他編程語言
可能不支持
一般都支持
和 、 、 的作用是一樣的。如果要從網頁中提取 ,不使用匹配模式的表達式應該是這樣:
標簽只有兩個字符,所以上面的寫法還可以接受。但是如果標簽是呢?這里,就需要使用不區分大小寫模式:/.../i或...(?i)...。上面的正則表達式可以進一步寫為:
/i或(?i)
preg_match("/(?i)
/", " ", $arr);
print_r($arr);
/*
Array
(
[0] =>
)
*/
單行模式
作用:點號可以匹配換行符
形式:/.../x或...(?m)...// (?#...)注釋
preg_match("/(?#this is comment)(?i)
/", " ", $arr);
print_r($arr);
/*
Array
(
[0] =>
)
*/
// /.../x注釋模式
$str = "/
(d{4}) # year
- # dash
(d{2}) # month
- # dash
(d{2}) # day
/x";
preg_match($str, "2015-10-01", $arr);
print_r($arr);
/*
Array
(
[0] => 2015-10-01
[1] => 2015
[2] => 10
[3] => 01
)
*/
非貪婪
// 默認貪婪匹配
$str = "
Unicode
hello ";
preg_match("/world .* /", $str, $arr);
print_r($arr);
/*
Array
(
[0] => hello
)
*/
// 非貪婪匹配模式
$str = "world hello ";
preg_match("/world .* /U", $str, $arr);
print_r($arr);
/*
Array
(
[0] =>
)
*/hello // 指定unicode模式
preg_match("/
[x{4e00}-x{9fff}]* /u", "姚明 ", $arr);
print_r($arr);
/*
Array
(
[0] => 姚明
)
*/相關文章
PHP正則表達式函數解析與正則表達式基本語法
搞定PHP面試 - 正則表達式知識點整理
php實戰正則表達式(二):提取html元素
PHP 正則表達式入門 Getting Started with PHP Regular Expre
發表評論
0條評論
lunaticf
男|高級講師
TA的文章
閱讀更多
集成 nacos注冊中心配置使用
html+css布局類型
【二次元的CSS】—— 用 DIV + CSS3 畫大白(詳解步驟)
扒一下W3C規范里的BFC和IFC
element ui table render-header自定義表頭信息使用
JS中的面向對象編程
面向切面編程與裝飾器
常用的幾個編碼風格規范