乌衣书影 發表於 2023-5-28 12:31:26

正则表达式之字符组简记法与字符组运算

<h2>字符组简记法</h2>
<p>用、等字符组,可以很方便地表示数字字符和小写字母字符。对于这类常用的字符组,正则表达式提供了更简单的记法,这就是字符组简记法(shorthands)。</p>
<p>常见的字符组简记法有\d、\w、\s。从表面上看,它们与[&hellip;]完全没联系,其实是一致的。其中\d等价于,其中的d代表&quot;数字(digit)&quot;;\w等价于,其中的w代表&quot;单词字符(word)&quot;;\s等价于[ \t\r\n\v\f](第一个字符是空格),s表示&quot;空白字符(space)&quot;。例1-17说明了这几个字符组简记法的典型匹配。</p>
<p>例1-17&nbsp; 字符组简记法\d、\w、\s</p>
<div class="jb51code"><pre class="brush:java;">#如果没有原生字符串,\d就必须写作\\d
re.search(r"^\d$", "8") != None   #=&gt; True
re.search(r"^\d$", "a") != None   #=&gt; False
re.search(r"^\w$", "8") != None   #=&gt; True
re.search(r"^\w$", "a") != None   #=&gt; True
re.search(r"^\w$", "_") != None   #=&gt; True
re.search(r"^\s$", " ") != None   #=&gt; True
re.search(r"^\s$", "\t") != None    #=&gt; True
re.search(r"^\s$", "\n") != None    #=&gt; True</pre></div>
<p>一般印象中,单词字符似乎只包含大小写字母,但是字符组简记法中的&quot;单词字符&quot;不只有大小写单词,还包括数字字符和下画线_,其中的下画线_尤其值得注意:在进行数据验证时,有可能只容许输入&quot;<code>数字和字母</code>&quot;,有人会偷懒用\w验证,而忽略了\w能匹配下画线,所以这种匹配并不严格,<code></code>才是准确的选择。</p>
<p>&quot;空白字符&quot;并不难定义,它可以是空格字符、制表符<code>\t</code>,回车符<code>\r</code>,换行符<code>\n</code>等各种&quot;空白&quot;字符,只是不方便展现(因为显示和印刷出来都是空白)。不过这也提醒我们注意,匹配时看到的&quot;空白&quot;可能不是空格字符,因此,<code>\s</code>才是准确的选择。</p>
<p>字符组简记法可以单独出现,也可以使用在字符组中,比如<code></code>也可以写作<code>[\da-zA-Z]</code>,所以匹配十六进制字符的字符组可以写成<code>[\da-fA-F]</code>。字符组简记法也可以用在排除型字符组中,比如[^0-9]就可以写成<code>[^\d]</code>,<code>[^0-9a-zA-Z_]</code>就可以写成[^\w],代码如例1-18。</p>
<p>例1-18&nbsp; 字符组简记法与普通字符组混用</p>
<div class="jb51code"><pre class="brush:java;">#用在普通字符组内部
re.search(r"^[\da-zA-Z]$", "8") != None#=&gt; True
re.search(r"^[\da-zA-Z]$", "a") != None#=&gt; True
re.search(r"^[\da-zA-Z]$", "C") != None#=&gt; True
#用在排除型字符组内部
re.search(r"^[^\w]$", "8") != None       #=&gt; False
re.search(r"^[^\w]$", "_") != None       #=&gt; False
re.search(r"^[^\w]$", ",") != None       #=&gt; True</pre></div>
<p>相对于\d、\w和\s这三个普通字符组简记法,正则表达式也提供了对应排除型字符组的简记法:\D、\W和\S--字母完全一样,只是改为大写。这些简记法匹配的字符互补:\s能匹配的字符,\S一定不能匹配;\w能匹配的字符,\W一定不能匹配;\d能匹配的字符,\D一定不能匹配。例1-19示范了这几个字符组简记法的应用。</p>
<p>例1-19&nbsp; \D、\W、\S的使用</p>
<div class="jb51code"><pre class="brush:java;">#\d和\D
re.search(r"^\d$", "8") != None   #=&gt; True
re.search(r"^\d$", "a") != None   #=&gt; False
re.search(r"^\D$", "8") != None   #=&gt; False
re.search(r"^\D$", "a") != None   #=&gt; True
#\w和\W
re.search(r"^\w$", "c") != None   #=&gt; True
re.search(r"^\w$", "!") != None   #=&gt; False
re.search(r"^\W$", "c") != None   #=&gt; False
re.search(r"^\W$", "!") != None   #=&gt; True
#\s和\S
re.search(r"^\s$", "\t") != None    #=&gt; True
re.search(r"^\s$", "0") != None   #=&gt; False
re.search(r"^\S$", "\t") != None    #=&gt; False
re.search(r"^\S$", "0") != None   #=&gt; True</pre></div>
<p>妥善利用这种互补的属性,可以得到一些非常巧妙的效果,最简单的应用就是字符组[\s\S]。初看起来,在同一个字符组中并列两个互补的简记法,这种做法有点奇怪,不过仔细想想就会明白,\s和\S组合在一起,匹配的就是&quot;所有的字符&quot;(或者叫&quot;任意字符&quot;)。许多语言中的正则表达式并没有直接提供&quot;任意字符&quot;的表示法,所以[\s\S]、[\w\W]、[\d\D]虽然看起来有点古怪,但确实可以匹配任意字符 。</p>
<p>关于字符组简记法,最后需要补充两点:第一,如果字符组中出现了字符组简记法,最好不要出现单独的-,否则可能引起错误,比如[\d-a]就很让人迷惑,在有些语言中,-会被作为普通字符,而在有些语言中,这样写会报错;第二,以上说的\d、\w、\s的匹配规则,都是针对ASCII编码而言的,也叫ASCII匹配规则。但是,目前一些语言中的正则表达式已经支持了Unicode字符,那么数字字符、单词字符、空白字符的范围,已经不仅仅限于ASCII编码中的字符。关于这个问题,具体细节在后文有详细的介绍,如果你现在就想知道,可以翻到第115页。</p>
<h3>正则表达式&mdash;&mdash;字符组运算</h3>
<p>以上介绍了字符组的基本功能,它们在常用的语言中都有提供;还有些语言中为字符组提供了更强大的功能,比如Java和.NET就提供了字符组运算的功能,可以在字符组内进行集合运算,在某些情况下这种功能非常实用。</p>
<p>如果要匹配所有的元音字母(为讲解简单考虑,暂时只考虑小写字母的情况),可以用,但是要匹配所有的辅音字母却没有什么方便的办法,最直接的写法是,不但烦琐,而且难理解。其实,从26个字母中&quot;减去&quot;元音字母,剩下的就是辅音字母,如果有办法做这个&quot;减法&quot;,就方便多了。</p>
<p>Java语言中提供了这样的字符组:[&amp;&amp;[^aeiou]],虽然初看有点古怪,但仔细看看,也不难理解。表示26个英文字母,[^aeiou]表示除元音字母之外的所有字符(还包括大写字母、数字和各种符号),两者取交集,就得到&quot;26个英文字母中,除去5个元音字母,剩下的21个辅音字母&quot;。</p>
<p>.NET中也有这样的功能,只是写法不一样。同样是匹配辅音字母的字符组,.NET中写作],其逻辑是:从能匹配的26个字符中,&quot;减去&quot;能匹配的元音字母。相对于Java,这种逻辑更符合直觉,但写法却有点古怪--不是[-],而是]。例1-20集中演示了Java和.NET中的字符组运算。</p>
<p>例1-20&nbsp; 字符组运算</p>
<div class="jb51code"><pre class="brush:java;">// Java
"a".matches("^[&amp;&amp;[^aeiou]]$");   //=&gt; TrueFalse
"b".matches("^[&amp;&amp;[^aeiou]]$");   //=&gt; False True
// .NET
Regex.IsMatch("^]$", "a");//=&gt; TrueFalse
Regex.IsMatch("^]$", "b");//=&gt; False True*红色为更正</pre></div>
頁: [1]
查看完整版本: 正则表达式之字符组简记法与字符组运算