zoukankan      html  css  js  c++  java
  • php中的正则函数:正则匹配,正则替换,正则分割 所有的操作都不会影响原来的字符串.

    ### 有一个长期的误解, 如果要分组, 必须用 小括号 和 |, 而不能用 中括号 和 |. `[ab|AB] `表示的不是 匹配 ab或 AB, 而是表示 匹配 a,b, |, A, B 这5个字符中 的任意 一个 字符. 要表示 匹配 ab或 AB, 必须/只能 用 `(ab|AB) `才可以

    总之, 使用 字符串函数 还是 使用 正则匹配, 主要看 被处理的 (通常是要被 匹配的或 要被替换的 字符串) 是 确定 的 不变的子串, 还是 不确定的, 如果是确定的, 已知的 那就用 字符串函数, 如果是不确定的, 模糊的 那就用 正则匹配, 当然 正则匹配由于需要 正则引擎的支持, 所以 效率和速度肯定 更慢.

    ### 要匹配单词的开头或结尾, 匹配 位置的时候, 有两种情形, 如果是在vim中, 使用的 匹配符号是 `<, > `, 但是, 如果是在 通用的 , perl正则表达式, php的 preg正则表达式, 则要用 `...` 这里的  表示的是 boundary 即边界 , 注意他匹配的是 "空格, 标点符号, 回车符等的位置 ", 是位置, 并不包含 空格 等这些 符号本身.

    要掌握一个函数,只要掌握其 参数 和返回值就可以了,参数要掌握完整的参数表, 包括那些可选参数。

    正则函数的 features:

    1.php的正则函数, 分为三种功能, 正则匹配match, 正则替换replace, 正则分割

    1. php的正则函数有两种体系,一种是pcre的pcre_... 一种是 posix体系的 ereg_ 或 eregi_...
    2. php的正则函数的参数顺序, 基本上都是相同的,即: funcName( $patter, [$replacement], $string, [$supplement])
    3. php的正则函数都 有 对应的 非正则函数版本,比如: 匹配的有 strpos, strstr, 字符串替换的有 str_replace, 字符串分解的有 explode, str_split等
    4. 是所有的 正则函数(和字符串 操作函数, 包括字符串分割/替换/匹配操作), 都不会对原来的字符串参数造成影响,通常只是对字符串参数的一个拷贝进行操作的。而且 现在的函数 都不允许 传引用 参数了.
    5. 而且大多字符串操作 函数, 都可以在 对应的 字符串参数位置 对 数组 进行操作.

    第一, 分割字符串,正则分割

    1. 分割后的结果,都是放在另外的一个数组中。
    2. 分割的方式有两种, 一种是 根据 指定的分割字符来分割,如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。

    正则表达式的 最小匹配原则

    要掌握正则表达式的几个匹配原则:

    1. 就是 默认的是 最长/贪婪匹配, 要实现 最小/懒惰匹配, 需要在 .* 的后面 加上? 因为问号是匹配 0次或1次, 所以 最多就是 匹配 一次. 这就是最小匹配原则 , 注意一定是 .* 后面加?, 而不是 在 字符元字符 的后面加上问号,比如 a*? 可能就是错误的??? 也就是最小匹配, 有一个固定的写法,就死 .*? 这里 起最小匹配 作用的是 ? 问号

    2. 最早先赢的原则: 最先匹配的字符 具有更高的优先级 the match that begins earliest wins

    3. 正向匹配原则, 不管是贪婪匹配, 还是最小匹配, 都是 遵循 从左到右的 匹配原则, 意思是说, 当一个 匹配开始后, 如果在中间 遇到 另一个 开头字符的时候, 他不会认为是另一个 匹配的开始....

    ==================

    第二, 替换字符串, 正则替换

    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等.

    同样的:

    1. 正则替换函数, 不会 改变原来的 原始 字符串.
    2. 下面是体现上述正则匹配几个原则的 首先匹配优先 最小匹配 的 一个 好例子:
    <?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

    #### 关键点: 1. 为什么要使用 $matches, 是因为 我们 匹配到了后, 要把 匹配到的 内容 取出来, 供后面使用, 也就是说, preg_match或 preg_match_all 具有 匹配/搜索和 /还有 截取的功能. 2. 为什么还有 $matches[0], [1], [2]? 是因为在匹配的时候, 为了模式的需要 在$pattern中, 可能 要用到 多个 小括号, 但是 我们 要取的 , 要使用的可能 不是 第一个, 也不是 整个 模式, 使用 要 用 $matches [2]... 3. 匹配模式字符串 中的 小括号? 小括号 是为了两个目的, 一个 是 为了表示一个整体(很多内容/字符串)的 多个次数 , 另一个 目的就是专门 为了 后面的 反向引用 而加上的... 参考: http://www.cnblogs.com/52php/p/5677640.html 4. 实用的例子: 从 一个 url地址中, 分别获取 主机名, 域名, 文件地址等的 正则表达式...



    关于几个特殊的正则匹配的符号 , 参考: https://zhidao.baidu.com/question/688350359585880164.html

    ? 问号 **这个就是懒惰 匹配的专用的符号** 既然是最小次数的 /懒惰 匹配, 所以 , 这个? 一定要放在 表示 次数的 元字符后面. 当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽 可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+” 将匹配所有“o”。

    . 点号
    匹配除“ ”之外的任何单个字符。要匹配包括“ ”在内的任何字符,请使用像“[. ]”的模式。

    还有 就是要 注意 几个 非获取匹配的, 比如 (?: 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”。    
    
    .
    匹配除“
    ”之外的任何单个字符。要匹配包括“
    ”在内的任何字符,请使用像“[.
    ]”的模式。    
    
    (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界面, 有两个地方需要 改动:

    1. 一是关于启动的选项中, 键盘方向键向右移动到BIOS"Startup"菜单,然后选择“CMS”按回车键 , 设置csM/cms 兼容支持模块为 enable.
    2. 二是, 设置 安全 secure(security) 中的 secure boot安全启动 , 将这个 关闭掉.
    3. 或者将UEFI/Legacy Boot修改为“Legacy only”, 再把UEFI/Legacy Boot Priority设置为Legacy First;

  • 相关阅读:
    在线报表设计实战系列 – 制作动态列与静态列混排的报表(5)
    在线报表设计实战系列 – 制作复杂表头报表(4)
    在线报表设计实战系列 – 制作交叉分析表(3)
    在线报表设计实战系列 – 制作表格类报表(2)
    在线报表设计实战系列 – 准备数据源(1)
    ActiveReports 报表控件V12新特性 -- RPX报表转换为RDL报表
    ActiveReports 报表控件V12新特性 -- 新增矩表的RepeatToFill属性
    HDU 2199 Can you solve this equation?_二分搜索
    POJ 1606 jugs(又是水壶问题)
    POJ 3414 Pots
  • 原文地址:https://www.cnblogs.com/bkylee/p/8301004.html
Copyright © 2011-2022 走看看