php中的正则函数:正则匹配,正则替换,正则分割 所有的操作都不会影响原来的字符串.
总之, 使用 字符串函数 还是 使用 正则匹配, 主要看 被处理的 (通常是要被 匹配的或 要被替换的 字符串) 是 确定 的 不变的子串, 还是 不确定的, 如果是确定的, 已知的 那就用 字符串函数, 如果是不确定的, 模糊的 那就用 正则匹配, 当然 正则匹配由于需要 正则引擎的支持, 所以 效率和速度肯定 更慢.
### 要匹配单词的开头或结尾, 匹配 位置的时候, 有两种情形, 如果是在vim中, 使用的 匹配符号是 `\<, \> `, 但是, 如果是在 通用的 , perl正则表达式, php的 preg正则表达式, 则要用 `\b...\b` 这里的 \b 表示的是 boundary 即边界 , 注意他匹配的是 "空格, 标点符号, 回车符等的位置 ", 是位置, 并不包含 空格 等这些 符号本身.要掌握一个函数,只要掌握其 参数 和返回值就可以了,参数要掌握完整的参数表, 包括那些可选参数。
正则函数的 features:
1.php的正则函数, 分为三种功能, 正则匹配match, 正则替换replace, 正则分割
- php的正则函数有两种体系,一种是pcre的pcre_... 一种是 posix体系的 ereg_ 或 eregi_...
- php的正则函数的参数顺序, 基本上都是相同的,即: funcName( \(patter, [\)replacement], \(string, [\)supplement])
- php的正则函数都 有 对应的 非正则函数版本,比如: 匹配的有 strpos, strstr, 字符串替换的有 str_replace, 字符串分解的有 explode, str_split等
- 是所有的 正则函数(和字符串 操作函数, 包括字符串分割/替换/匹配操作), 都不会对原来的字符串参数造成影响,通常只是对字符串参数的一个拷贝进行操作的。而且 现在的函数 都不允许 传引用 参数了.
- 而且大多字符串操作 函数, 都可以在 对应的 字符串参数位置 对 数组 进行操作.
第一, 分割字符串,正则分割
- 分割后的结果,都是放在另外的一个数组中。
- 分割的方式有两种, 一种是 根据 指定的分割字符来分割,如preg_split, split, explode; 另一种是 根据指定的 "等数" 字符数来分割,如str_split
\(split_result = preg_split(\)patter, \(string [,\)limit] [,$flags])
与他类似的posix函数 split: \(result = split(\)patter, \(string [,\)limit])
返回结果: 返回分解后的单元,放在 函数外部的 另外的一个 数组变量来接收。
可能的分解情况:
- 分解模式$patter没有包含原字符串中, 则返回整个字符串的 单元素数组;
- 分解模式 $patter=//, 即模式字符串中不包含任何东西,则会将原字符串的拷贝 分解为一个一个的字符。并且首尾会多两个空白元素
- 其他正常分解模式。
\(limit 是指 **最多*分解成(并返回)\)limit 个分解单元, 这个参数最容易被误解,它不是说先把整个字符串分割,然后返回
\(limit个子串,然后剩下的就不要了,实际上不是这样的,正确的意思是: 每次分割总是要把全部字符串分割完并
返回,而是说 **整个**字符串最多分割成\)limit个子串。 如果不确定,要全部返回就用 -1.
$flag,说的是返回的子串应该满足些什么条件,最常用的有一个: PREG_SPLIT_NO_EMPTY。
正则表达式的 最小匹配原则
要掌握正则表达式的几个匹配原则:
-
就是 默认的是 最长/贪婪匹配, 要实现 最小/懒惰匹配, 需要在
.*
的后面 加上? 因为问号是匹配 0次或1次, 所以 最多就是 匹配 一次. 这就是最小匹配原则 , 注意一定是 .* 后面加?, 而不是 在 字符元字符 的后面加上问号,比如a*?
可能就是错误的??? 也就是最小匹配, 有一个固定的写法,就死.*?
这里 起最小匹配 作用的是 ? 问号 -
最早先赢的原则: 最先匹配的字符 具有更高的优先级 the match that begins earliest wins
-
正向匹配原则, 不管是贪婪匹配, 还是最小匹配, 都是 遵循 从左到右的 匹配原则, 意思是说, 当一个 匹配开始后, 如果在中间 遇到 另一个 开头字符的时候, 他不会认为是另一个 匹配的开始....
==================
第二, 替换字符串, 正则替换
str_replace的原型:
$result_after_replace = str_replace( $find, $replacement, $str [, \(count_replace])
这个函数中, 不允许传引用参数, 最后的那个可选参数是 被替换的次数.
如果\)find $replacement是数组, 则表示 一对一 替换.
[@str_replace("要替换的旧内容", "要取代原内容的新字符", $被替换内容的变量名)]
[@str_replace(array('旧1','旧2','旧3'), array('新1','新2','新3'), $被替换内容的变量名)] // 一对一替换
[@str_replace(array('旧1','旧2','旧3'), '新内容', $被替换内容的变量名)] // 一对多替换.
正则替换的函数原型: \(result_after_replace = preg_replace(\)pattern, $replacement, \(string [, [\)limit=-1] [, $replaceCount]]) 跟 str_replace有些类似.
同样的 也可以 处理 数组, $pattern 和 $replace 都可以是数组, 替换法则也是一样, 只是多了一个 \(limit 参数.
而且 在 数组的 正则替换中, 可以使用 后向引用, 在后向引用中, 使用 `\)n来表示 模式中的 部分. 如果
\(n` 后面还有其他 数字或字母, 为了区别, 要将 n用大括号括起来. `\){n}abc`等.
同样的:
- 正则替换函数, 不会 改变原来的 原始 字符串.
- 下面是体现上述正则匹配几个原则的 首先匹配优先\ 最小匹配 \ 的 一个 好例子:
<?php
$str="abc 123 efg a4b xyz, m60n,AB";
print_r(preg_replace('/\d.*?\d/', 'D', $str));
echo '<br>';
print_r($str);
输出结果:
abc DDb xyz, mDn,AB
abc 123 efg a4b xyz, m60n,AB
=================
第三, 匹配字符串, 正则匹配, 匹配函数的意思和目的, 是指 "判断某个字符串中, 是否包含 某个 子串"
对应的字符串函数, 是 strstr, strpos
而对应的 正则匹配函数包括 preg_match($pattern, $string [, $matches] )
注意, preg_match会短路, 只匹配一次, 如果匹配到了, 则不再匹配, 匹配后的结果 放在 $matches中
要 全部搜索 匹配完, 则 要使用 preg_match_all
关于几个特殊的正则匹配的符号 , 参考: https://zhidao.baidu.com/question/688350359585880164.html
? 问号 **这个就是懒惰 匹配的专用的符号** 既然是最小次数的 /懒惰 匹配, 所以 , 这个? 一定要放在 表示 次数的 元字符后面. 当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽 可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+” 将匹配所有“o”。. 点号
匹配除“\n”之外的任何单个字符。要匹配包括“\n”在内的任何字符,请使用像“[.\n]”的模式。
还有 就是要 注意 几个 非获取匹配的, 比如 (?: abc|ABC) (?= abc|ABC) (?! abc|ABC) 预匹配的查询....
最基本的意思:小括号就是括号内看成一个整体 ,中括号就是匹配括号内的其中一个,大括号就是匹配几次
但是括号里变加上其他字符就有不同意思 详细介绍 例如:
{n}
n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。
{n,}
n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。
{n,m}
m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。
?
当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽
可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+”
将匹配所有“o”。
.
匹配除“\n”之外的任何单个字符。要匹配包括“\n”在内的任何字符,请使用像“[.\n]”的模式。
(pattern)
匹配pattern并获取这一匹配。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用$0…$9属性。要匹配圆括号字符,请使用“\(”或“\)”。
(?:pattern)
匹配pattern但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分是很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。
(?=pattern)
正向预查,在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后
使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配
“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从
包含预查的字符之后开始。
(?!pattern)
负向预查,在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以
后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配
“Windows2000”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是
从包含预查的字符之后开始
x|y
匹配x或y。例如,“z|food”能匹配“z”或“food”。“(z|f)ood”则匹配“zood”或“food”。
[xyz]
字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。
[^xyz]
负值字符集合。匹配未包含的任意字符。例如,“[^abc]”可以匹配“plain”中的“p”。
[a-z]
字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。
[^a-z]
负值字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。
正则中的小括号,作用有3种:
- 是 为了将 一部分内容作为一个整体来看待, 后面要说明这个整体内容的次数时, 比如
/(http:\/\/)?/
- 是为了表示分组, 比如:
industr(?:y|ies)
或者(abc|ABC)
- 是为了表示/便于后面的反向引用, 当后面要引用其中的某个 匹配部分时, 专门用小括号来表示。因为如果你要取出其中某一部分, 如果
你不用小括号, 你就取不到。
在匹配模式字符串中, 有的只是为了限定模式,为了匹配的需要,而输入的内容,而常常我们需要的内容只是匹配字符串中的
某一部分而已。 这个需要的部分就用括号把它取出来。
php正则匹配函数 preg_match(...) / 正则表达式的例子
<?php
$url = "http://www.baidu.com/article/index.php";
$url2 = "Https://www2.baidu2.com/article/news/index2.php";
$url3 = "www3.baidu3.com/index3.php";
/* 取出最后的文件名index.php */
if(preg_match('/\w.*\/(\w+\.php)/', $url, $matches)){
echo '<br>匹配的文件名是: '.$matches[1]."<br>";
}
if(preg_match('/\w.*\/(\w+\.php)/', $url2, $matches)){
echo '<br>匹配的文件名是: '.$matches[1]."<br>";
}
if(preg_match('/\w.*\/(\w+\.php)/', $url3, $matches)){
echo '<br>匹配的文件名是: '.$matches[1]."<br>";
}
echo "================================";
/* 取出主机名www,www2, www3 */
if(preg_match('/(https?:\/\/)?(\w+)\.?/', $url, $matches)){
echo '<br>匹配的主机名是: '.$matches[2]."<br>";
}
if(preg_match('/(https?:\/\/)?(\w+)\.?/i', $url2, $matches)){
echo '<br>匹配的主机名是: '.$matches[2]."<br>";
}
if(preg_match('/(https?:\/\/)?(\w+)\.?/', $url3, $matches)){
echo '<br>匹配的主机名是: '.$matches[2]."<br>";
}
echo "================================";
/* 取出 域名 baidu.com, baidu2.com., baidu3.com */
// 如果包含的斜线太多,可以使用# 或 @ 等符号作为 定界符
// 下面的 \. 就是表示只有一个点号,因此,不一定 点号都要用星号或加号
// 注意问号的用法: 如果是在字符元字符后面, 它表示的是0个或1个, 是次数元字符, 只有在 前面已经有一个“次数元字符”了, 后面再加上问号的时候, 才表示 懒惰匹配。
// 由此看出, 这个懒惰匹配还是非常重要的! 在正则模式处理中,可以说是随时都要用到的!
if(preg_match('#(https?://)?\w+\.(\w+.*)/#i', $url, $matches)){
echo '<br>匹配的域名是(这个没有使用最小匹配): '.$matches[2]."<br>";
}
//下面这个语句和上面那条 语句 相比 就是最小匹配的好例子。
if(preg_match('#(https?://)?\w+\.(\w+.*?)/#i', $url, $matches)){
echo '<br>匹配的域名是: '.$matches[2]."<br>";
}
if(preg_match('#(https?://)?\w+\.(\w+.*?)/#i', $url2, $matches)){
echo '<br>匹配的域名是: '.$matches[2]."<br>";
}
if(preg_match('#(https?://)?\w+\.(\w+.*?)/#i', $url3, $matches)){
echo '<br>匹配的域名是: '.$matches[2]."<br>";
}
?>
输出结果是
匹配的文件名是: index.php
匹配的文件名是: index2.php
匹配的文件名是: index3.php
================================
匹配的主机名是: www
匹配的主机名是: www2
匹配的主机名是: www3
================================
匹配的域名是(这个没有使用最小匹配): baidu.com/article
匹配的域名是: baidu.com
匹配的域名是: baidu2.com
匹配的域名是: baidu3.com
杂项
uefi: 统一的 可扩展固件接口, 像win8 win10等 就是用的uefi接口.
CSM(Compatibility support Module)表示兼容模块,该选项专为兼容只能在legacy模式下工作的设备以及不支持或不能完全支持UEFI的操作系统而设置
CSM 设为Enable,Boot Mode启动方式可以选择Legacy only(仅Legacy)
进入BIOS界面, 有两个地方需要 改动:
- 一是关于启动的选项中, 键盘方向键向右移动到BIOS"Startup"菜单,然后选择“CMS”按回车键 , 设置csM/cms 兼容支持模块为 enable.
- 二是, 设置 安全 secure(security) 中的 secure boot安全启动 , 将这个 关闭掉.
- 或者将UEFI/Legacy Boot修改为“Legacy only”, 再把UEFI/Legacy Boot Priority设置为Legacy First;