642 lines
82 KiB
HTML
642 lines
82 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh" dir="ltr" class="client-nojs" xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh">
|
|
<head><meta http-equiv="x-ua-compatible" content="ie=edge">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<title>改 ECMAScript 正则表达式文法</title>
|
|
<link rel="stylesheet" href="ext.css" />
|
|
<link rel="stylesheet" href="site_modules.css" />
|
|
</head>
|
|
<body class="mediawiki ltr sitedir-ltr ns-0 ns-subject page-cpp_regex_ecmascript skin-cppreference2 action-view cpp-navbar">
|
|
<div id="cpp-content-base">
|
|
<div id="content"><a id="top"></a>
|
|
<h1 id="firstHeading" class="firstHeading">改 ECMAScript 正则表达式文法</h1>
|
|
<div id="bodyContent">
|
|
<div id="contentSub"><span class="subpages">< <a href="cpp.html">cpp</a>‎ | <a href="cpp-regex.html">regex</a></span></div>
|
|
<div id="mw-content-text" lang="zh" dir="ltr" class="mw-content-ltr" xml:lang="zh">
|
|
<p>此页面描述以设置为 <code>ECMAScript</code> (默认值)的 <a href="cpp-regex-syntax_option_type.html"><tt>syntax_option_type</tt></a> 构造 <span class="t-lc"><a href="cpp-regex-basic_regex.html">std::basic_regex</a></span> 时使用的文法。其他受支持正则表达式文法见 <a href="cpp-regex-syntax_option_type.html"><tt>syntax_option_type</tt></a> 。</p>
|
|
<p>C++ 中的 <code>ECMAScript</code> 3 正则表达式文法是带标记有后述 <span class="t-mark">(仅 C++)</span> 的修改的 <a rel="nofollow" class="external text" href="http://ecma-international.org/ecma-262/5.1/#sec-15.10">ECMA-262 文法</a>。</p>
|
|
<h3><span class="mw-headline" id=".E6.80.BB.E8.A7.88">总览</span></h3>
|
|
<p><a rel="nofollow" class="external text" href="https://eel.is/c++draft/re.grammar">改正则表达式文法</a>几乎是 ECMAScript RegExp 文法带上<i>类原子 (ClassAtom)</i> 下的本地环境上的 POSIX 类型展开。我们作出了相等检查与数量分析上的一些澄清。对于此处的多数示例,你可以在你的浏览器控制台中尝试此等价版本:</p>
|
|
<pre>function match(s, re) { return s.match(new RegExp(re)); }
|
|
</pre>
|
|
<p>标准中的“正式引用”指定 ECMAScript 3 。我们于此链接到 ECMAScript 5.1 规范,因为其正则表达式文法相比 ECMAScript 3 仅有微小改动,而且它有一个 HTML 版本。方言特性的概览见 <a rel="nofollow" class="external text" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions">MDN Guide on JavaScript RegExp</a> 。</p>
|
|
<h3><span class="mw-headline" id=".E5.8F.AF.E9.80.89.E9.A1.B9">可选项</span></h3>
|
|
<p>正则表达式模式是一或多个以析取运算符 <code><b>|</b></code> 分隔的可选项<i>可选项 (Alternative)</i> 序列(换言之,析取运算符拥有最低优先级)</p>
|
|
<p><i>Pattern</i> ::</p>
|
|
<dl>
|
|
<dd><i>Disjunction</i></dd>
|
|
</dl>
|
|
<p><i>Disjunction</i> ::</p>
|
|
<dl>
|
|
<dd><i>Alternative</i></dd>
|
|
<dd><i>Alternative</i> <code><b>|</b></code> <i>Disjunction</i></dd>
|
|
</dl>
|
|
<p>模式首先尝试跳过<i>析取 (Disjunction)</i> 并匹配(析取后的)后随剩余正则表达式的<i>可选项</i>。</p>
|
|
<p>若它失败,则试图跳过左侧<i>可选项</i>并匹配右侧<i>析取</i>(后随剩余正则表达式)。</p>
|
|
<p>若左侧<i>可选项</i>、右侧<i>析取</i>和剩余正则表达式都拥有选择点,则在尝试移动到左侧<i>可选项</i>中的下个选择前,尝试剩余表达式值中的所有选择。若穷尽了左侧<i>可选项</i>中的所有选择,则取代左侧<i>可选项</i>尝试右侧<i>析取</i>。</p>
|
|
<p>跳过的<i>可选项</i>内的任何捕获括号产生空子匹配。</p>
|
|
<div class="t-example">
|
|
<div class="t-example-live-link"></div>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="co2">#include <iostream></span>
|
|
<span class="co2">#include <regex></span>
|
|
|
|
<span class="co1">// TODO :转换到接受宽字符序列</span>
|
|
<span class="co1">// std::match_results<std::basic_string<_ch>::const_iterator> m; 不行。</span>
|
|
<span class="kw4">void</span> show_matches<span class="br0">(</span><span class="kw4">const</span> <a href="cpp-string-basic_string.html"><span class="kw1230">std::<span class="me2">string</span></span></a><span class="sy3">&</span> in, <span class="kw4">const</span> <a href="cpp-string-basic_string.html"><span class="kw1230">std::<span class="me2">string</span></span></a><span class="sy3">&</span> re<span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<a href="cpp-regex-match_results.html"><span class="kw2010">std::<span class="me2">smatch</span></span></a> m<span class="sy4">;</span>
|
|
<a href="cpp-regex-regex_search.html"><span class="kw2013">std::<span class="me2">regex_search</span></span></a><span class="br0">(</span>in, m, <a href="cpp-regex-basic_regex.html"><span class="kw2000">std::<span class="me2">regex</span></span></a><span class="br0">(</span>re<span class="br0">)</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="kw1">if</span><span class="br0">(</span>m.<span class="me1">empty</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"input=["</span> <span class="sy1"><<</span> in <span class="sy1"><<</span> <span class="st0">"], regex=["</span> <span class="sy1"><<</span> re <span class="sy1"><<</span> <span class="st0">"]: NO MATCH<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
<span class="br0">}</span> <span class="kw1">else</span> <span class="br0">{</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"input=["</span> <span class="sy1"><<</span> in <span class="sy1"><<</span> <span class="st0">"], regex=["</span> <span class="sy1"><<</span> re <span class="sy1"><<</span> <span class="st0">"]: "</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"prefix=["</span> <span class="sy1"><<</span> m.<span class="me1">prefix</span><span class="br0">(</span><span class="br0">)</span> <span class="sy1"><<</span> <span class="st0">"] "</span><span class="sy4">;</span>
|
|
<span class="kw1">for</span><span class="br0">(</span><a href="cpp-types-size_t.html"><span class="kw100">std::<span class="me2">size_t</span></span></a> n <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span> n <span class="sy1"><</span> m.<span class="me1">size</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="sy2">++</span>n<span class="br0">)</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">" m["</span> <span class="sy1"><<</span> n <span class="sy1"><<</span> <span class="st0">"]=["</span> <span class="sy1"><<</span> m<span class="br0">[</span>n<span class="br0">]</span> <span class="sy1"><<</span> <span class="st0">"] "</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"suffix=["</span> <span class="sy1"><<</span> m.<span class="me1">suffix</span><span class="br0">(</span><span class="br0">)</span> <span class="sy1"><<</span> <span class="st0">"]<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
<span class="br0">}</span>
|
|
|
|
<span class="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
show_matches<span class="br0">(</span><span class="st0">"abcdef"</span>, <span class="st0">"abc|def"</span><span class="br0">)</span><span class="sy4">;</span>
|
|
show_matches<span class="br0">(</span><span class="st0">"abc"</span>, <span class="st0">"ab|abc"</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 首先匹配左侧可选项</span>
|
|
|
|
<span class="co1">// 针对后随剩余正则表达式 (c|bc) 左侧可选项 (a) 的匹配成功</span>
|
|
<span class="co1">// 它生成 m[1]="a" 及 m[4]="bc" 。</span>
|
|
<span class="co1">// 跳过的可选项 (ab) 和 (c) 将其子匹配 m[3] 和 m[5] 置为空。</span>
|
|
show_matches<span class="br0">(</span><span class="st0">"abc"</span>, <span class="st0">"((a)|(ab))((c)|(bc))"</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>输出:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="text source-text">
|
|
<pre class="de1">input=[abcdef], regex=[abc|def]: prefix=[] m[0]=[abc] suffix=[def]
|
|
input=[abc], regex=[ab|abc]: prefix=[] m[0]=[ab] suffix=[c]
|
|
input=[abc], regex=[((a)|(ab))((c)|(bc))]: prefix=[] m[0]=[abc]
|
|
m[1]=[a] m[2]=[a] m[3]=[] m[4]=[bc] m[5]=[] m[6]=[bc] suffix=[]</pre></div>
|
|
</div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E9.A1.B9">项</span></h3>
|
|
<p>每个<i>可选项</i>为空,或为<i>项 (Term)</i> 的序列(<i>项</i>间无分隔符)</p>
|
|
<p><i>Alternative</i> ::</p>
|
|
<dl>
|
|
<dd><i>[empty]</i></dd>
|
|
<dd><i>Alternative</i> <i>Term</i></dd>
|
|
</dl>
|
|
<p>空的<i>可选项</i>始终匹配并且不消耗任何输入。</p>
|
|
<p>相继的<i>项</i>尝试同时匹配输入的连续部分。</p>
|
|
<p>若左侧<i>可选项</i>、右侧<i>项</i>和剩余正则表达式拥有选择点,则在移动到右侧<i>项</i>中的下个选择前,尝试剩余正则表达式中的所有选择,并在移动到左侧<i>可选项</i>中的下个选择前,尝试右侧<i>项</i>中的所有选择。</p>
|
|
<div class="t-example">
|
|
<div class="t-example-live-link"></div>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="co2">#include <iostream></span>
|
|
<span class="co2">#include <regex></span>
|
|
|
|
<span class="co1">// TODO :转换到接受宽字符序列</span>
|
|
<span class="co1">// std::match_results<std::basic_string<_ch>::const_iterator> m; 不行。</span>
|
|
<span class="kw4">void</span> show_matches<span class="br0">(</span><span class="kw4">const</span> <a href="cpp-string-basic_string.html"><span class="kw1230">std::<span class="me2">string</span></span></a><span class="sy3">&</span> in, <span class="kw4">const</span> <a href="cpp-string-basic_string.html"><span class="kw1230">std::<span class="me2">string</span></span></a><span class="sy3">&</span> re<span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<a href="cpp-regex-match_results.html"><span class="kw2010">std::<span class="me2">smatch</span></span></a> m<span class="sy4">;</span>
|
|
<a href="cpp-regex-regex_search.html"><span class="kw2013">std::<span class="me2">regex_search</span></span></a><span class="br0">(</span>in, m, <a href="cpp-regex-basic_regex.html"><span class="kw2000">std::<span class="me2">regex</span></span></a><span class="br0">(</span>re<span class="br0">)</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="kw1">if</span><span class="br0">(</span>m.<span class="me1">empty</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"input=["</span> <span class="sy1"><<</span> in <span class="sy1"><<</span> <span class="st0">"], regex=["</span> <span class="sy1"><<</span> re <span class="sy1"><<</span> <span class="st0">"]: NO MATCH<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
<span class="br0">}</span> <span class="kw1">else</span> <span class="br0">{</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"input=["</span> <span class="sy1"><<</span> in <span class="sy1"><<</span> <span class="st0">"], regex=["</span> <span class="sy1"><<</span> re <span class="sy1"><<</span> <span class="st0">"]: "</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"prefix=["</span> <span class="sy1"><<</span> m.<span class="me1">prefix</span><span class="br0">(</span><span class="br0">)</span> <span class="sy1"><<</span> <span class="st0">"] "</span><span class="sy4">;</span>
|
|
<span class="kw1">for</span><span class="br0">(</span><a href="cpp-types-size_t.html"><span class="kw100">std::<span class="me2">size_t</span></span></a> n <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span> n <span class="sy1"><</span> m.<span class="me1">size</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="sy2">++</span>n<span class="br0">)</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">" m["</span> <span class="sy1"><<</span> n <span class="sy1"><<</span> <span class="st0">"]=["</span> <span class="sy1"><<</span> m<span class="br0">[</span>n<span class="br0">]</span> <span class="sy1"><<</span> <span class="st0">"] "</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"suffix=["</span> <span class="sy1"><<</span> m.<span class="me1">suffix</span><span class="br0">(</span><span class="br0">)</span> <span class="sy1"><<</span> <span class="st0">"]<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
<span class="br0">}</span>
|
|
|
|
<span class="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
show_matches<span class="br0">(</span><span class="st0">"abcdef"</span>, <span class="st0">""</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 空正则表达式是单个空可选项</span>
|
|
show_matches<span class="br0">(</span><span class="st0">"abc"</span>, <span class="st0">"abc|"</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 左可选项首先匹配</span>
|
|
show_matches<span class="br0">(</span><span class="st0">"abc"</span>, <span class="st0">"|abc"</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 左可选项首先匹配,留待 abc 未匹配</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>输出:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="text source-text">
|
|
<pre class="de1">input=[abcdef], regex=[]: prefix=[] m[0]=[] suffix=[abcdef]
|
|
input=[abc], regex=[abc|]: prefix=[] m[0]=[abc] suffix=[]
|
|
input=[abc], regex=[|abc]: prefix=[] m[0]=[] suffix=[abc]</pre></div>
|
|
</div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E6.95.B0.E9.87.8F.E8.AF.8D">数量词</span></h3>
|
|
<ul>
|
|
<li>每个<i>项</i> 为<i>断言 (Assertion)</i>(见后方)或<i>原子 (Atom)</i> (见后方),或<i>原子</i>立即后随<i>数量词 (Quantifier)</i> 之一</li>
|
|
</ul>
|
|
<p><i>Term</i> ::</p>
|
|
<dl>
|
|
<dd><i>Assertion</i></dd>
|
|
<dd><i>Atom</i></dd>
|
|
<dd><i>Atom</i> <i>Quantifier</i></dd>
|
|
</dl>
|
|
<p>每个<i>数量词</i>为<i>贪心 (greedy)</i> 数量词(仅由一个<i>数量词前缀 (QuantifierPrefix)</i> 组成)或<i>非贪心 (non-greedy)</i> 数量词(由一个<i>数量词前缀</i>后随问号掩码 <code><b>?</b></code> 组成)。</p>
|
|
<p><i>Quantifier</i> ::</p>
|
|
<dl>
|
|
<dd><i>QuantifierPrefix</i></dd>
|
|
<dd><i>QuantifierPrefix</i> <code><b>?</b></code></dd>
|
|
</dl>
|
|
<p>每个<i>数量词前缀</i>确定二个数:最小重复数和最大重复数,如下:</p>
|
|
<table class="wikitable">
|
|
<tr>
|
|
<th>数量词前缀</th>
|
|
<th>最小</th>
|
|
<th>最大</th>
|
|
</tr>
|
|
<tr>
|
|
<td><code><b>*</b></code></td>
|
|
<td>零</td>
|
|
<td>无穷大</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code><b>+</b></code></td>
|
|
<td>一</td>
|
|
<td>无穷大</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code><b>?</b></code></td>
|
|
<td>零</td>
|
|
<td>一</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code><b>{</b></code> <i>十进制数</i> <code><b>}</b></code></td>
|
|
<td>十进制数的值</td>
|
|
<td>十进制数的值</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code><b>{</b></code> <i>十进制数</i> <code><b>,</b></code> <code><b>}</b></code></td>
|
|
<td>十进制数的值</td>
|
|
<td>无穷大</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code><b>{</b></code> <i>十进制数</i> <code><b>,</b></code> <i>十进制数</i> <code><b>}</b></code></td>
|
|
<td>逗号前的十进制数的值</td>
|
|
<td>逗号后的十进制数的值</td>
|
|
</tr>
|
|
</table>
|
|
<p>通过在每个数位上调用 <span class="t-lc"><a href="cpp-regex-regex_traits-value.html">std::regex_traits::value</a></span><span class="t-mark">(仅 C++)</span>获得单独的<i>十进制数 (DecimalDigits)</i> 的值。</p>
|
|
<p><i>原子</i>后随<i>数量词</i>重复<i>数量词</i>所指定的次数。<i>数量词</i>能为<i>非贪心</i>,该情况下<i>原子</i>模式重复在仍然匹配剩余正则表达式的同时尽可能少的次数,或能为<i>贪心</i>,该情况下<i>原子</i>模式重复在仍然匹配剩余正则表达式的同时尽可能多的次数。</p>
|
|
<p>重复的是<i>原子</i>模式,而非其所匹配的输入,故<i>原子</i>的不同重复能匹配不同的输入子串。</p>
|
|
<p>若<i>原子</i>和剩余正则表达式都有选择点,则首先将<i>原子</i>匹配尽可能尽可能多(或少,若为<i>非贪心</i>)次。,移动到<i>原子</i>的最后一次重复中的下个选择前,尝试剩余正则表达式中的所有选择。移动到<i>原子</i>的倒数第二(第 n-1 )次重复中的下个选择前,尝试<i>原子</i>的最后一(第 n )次重复中的所有选择;在明确现在可能有<i>原子</i>的更多或更少重复时;在移动到<i>原子</i>的第 n-1 次重复中的下个选择前,将这些穷尽(再次以尽可能少或多开始),以此类推。</p>
|
|
<p>每次重复<i>原子'</i>时,清除其捕获(见后方 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="st0">"(z)((a+)?(b+)?(c))*"</span></span></span> 的示例)</p>
|
|
<div class="t-example">
|
|
<div class="t-example-live-link"></div>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="co2">#include <iostream></span>
|
|
<span class="co2">#include <regex></span>
|
|
|
|
<span class="co1">// TODO :转换到接受宽字符序列</span>
|
|
<span class="co1">// std::match_results<std::basic_string<_ch>::const_iterator> m; 不行。</span>
|
|
<span class="kw4">void</span> show_matches<span class="br0">(</span><span class="kw4">const</span> <a href="cpp-string-basic_string.html"><span class="kw1230">std::<span class="me2">string</span></span></a><span class="sy3">&</span> in, <span class="kw4">const</span> <a href="cpp-string-basic_string.html"><span class="kw1230">std::<span class="me2">string</span></span></a><span class="sy3">&</span> re<span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<a href="cpp-regex-match_results.html"><span class="kw2010">std::<span class="me2">smatch</span></span></a> m<span class="sy4">;</span>
|
|
<a href="cpp-regex-regex_search.html"><span class="kw2013">std::<span class="me2">regex_search</span></span></a><span class="br0">(</span>in, m, <a href="cpp-regex-basic_regex.html"><span class="kw2000">std::<span class="me2">regex</span></span></a><span class="br0">(</span>re<span class="br0">)</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="kw1">if</span><span class="br0">(</span>m.<span class="me1">empty</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"input=["</span> <span class="sy1"><<</span> in <span class="sy1"><<</span> <span class="st0">"], regex=["</span> <span class="sy1"><<</span> re <span class="sy1"><<</span> <span class="st0">"]: NO MATCH<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
<span class="br0">}</span> <span class="kw1">else</span> <span class="br0">{</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"input=["</span> <span class="sy1"><<</span> in <span class="sy1"><<</span> <span class="st0">"], regex=["</span> <span class="sy1"><<</span> re <span class="sy1"><<</span> <span class="st0">"]: "</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"prefix=["</span> <span class="sy1"><<</span> m.<span class="me1">prefix</span><span class="br0">(</span><span class="br0">)</span> <span class="sy1"><<</span> <span class="st0">"] "</span><span class="sy4">;</span>
|
|
<span class="kw1">for</span><span class="br0">(</span><a href="cpp-types-size_t.html"><span class="kw100">std::<span class="me2">size_t</span></span></a> n <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span> n <span class="sy1"><</span> m.<span class="me1">size</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="sy2">++</span>n<span class="br0">)</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">" m["</span> <span class="sy1"><<</span> n <span class="sy1"><<</span> <span class="st0">"]=["</span> <span class="sy1"><<</span> m<span class="br0">[</span>n<span class="br0">]</span> <span class="sy1"><<</span> <span class="st0">"] "</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"suffix=["</span> <span class="sy1"><<</span> m.<span class="me1">suffix</span><span class="br0">(</span><span class="br0">)</span> <span class="sy1"><<</span> <span class="st0">"]<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
<span class="br0">}</span>
|
|
|
|
<span class="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="co1">// 贪心匹配,重复 [a-z] 4 次</span>
|
|
show_matches<span class="br0">(</span><span class="st0">"abcdefghi"</span>, <span class="st0">"a[a-z]{2,4}"</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="co1">// 非贪心匹配,重复 [a-z] 2 次</span>
|
|
show_matches<span class="br0">(</span><span class="st0">"abcdefghi"</span>, <span class="st0">"a[a-z]{2,4}?"</span><span class="br0">)</span><span class="sy4">;</span>
|
|
|
|
<span class="co1">// 数量词的选择点顺序,生成带二个重复的匹配,</span>
|
|
<span class="co1">// 第一个匹配子串 "aa" ,第二个匹配子串 "ba" ,保留 "ac" 匹配</span>
|
|
<span class="co1">// ("ba" 出现于 m[1] 的捕获子句中)</span>
|
|
show_matches<span class="br0">(</span><span class="st0">"aabaac"</span>, <span class="st0">"(aa|aabaac|ba|b|c)*"</span><span class="br0">)</span><span class="sy4">;</span>
|
|
|
|
<span class="co1">// 数量词的选择点顺序令此 regex 计算 10 与 15 间的最大公约数</span>
|
|
<span class="co1">// (答案是 5 ,并以 "aaaaa" 填充 m[1] )</span>
|
|
show_matches<span class="br0">(</span><span class="st0">"aaaaaaaaaa,aaaaaaaaaaaaaaa"</span>, <span class="st0">"^(a+)<span class="es1">\\</span>1*,<span class="es1">\\</span>1+$"</span><span class="br0">)</span><span class="sy4">;</span>
|
|
|
|
<span class="co1">// 子串 "bbb" 不出现于捕获子句 m[4] 中</span>
|
|
<span class="co1">// 因为它在原子 (a+)?(b+)?(c) 的第二次重复匹配子串 "ac" 时被声明</span>
|
|
<span class="co1">// 注: gcc 理解有误——它没有正确地按 ECMA-262 21.2.2.5.1 清除</span>
|
|
<span class="co1">// matches[4] 捕获组,从而错误地对于该组捕获 "bbb" 。</span>
|
|
show_matches<span class="br0">(</span><span class="st0">"zaacbbbcac"</span>, <span class="st0">"(z)((a+)?(b+)?(c))*"</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>输出:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="text source-text">
|
|
<pre class="de1">input=[abcdefghi], regex=[a[a-z]{2,4}]: prefix=[] m[0]=[abcde] suffix=[fghi]
|
|
input=[abcdefghi], regex=[a[a-z]{2,4}?]: prefix=[] m[0]=[abc] suffix=[defghi]
|
|
input=[aabaac], regex=[(aa|aabaac|ba|b|c)*]:
|
|
prefix=[] m[0]=[aaba] m[1]=[ba] suffix=[ac]
|
|
input=[aaaaaaaaaa,aaaaaaaaaaaaaaa], regex=[^(a+)\1*,\1+$]:
|
|
prefix=[] m[0]=[aaaaaaaaaa,aaaaaaaaaaaaaaa] m[1]=[aaaaa] suffix=[]
|
|
input=[zaacbbbcac], regex=[(z)((a+)?(b+)?(c))*]:
|
|
prefix=[] m[0]=[zaacbbbcac] m[1]=[z] m[2]=[ac] m[3]=[a] m[4]=[] m[5]=[c] suffix=[]</pre></div>
|
|
</div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E6.96.AD.E8.A8.80">断言</span></h3>
|
|
<p><i>断言 (Assertion)</i> 匹配条件,而非输入字符串的子串。它们决不消耗任何来自输入的字符。每个<i>断言</i>是下列之一</p>
|
|
<p><i>Assertion</i> ::</p>
|
|
<dl>
|
|
<dd><code><b>^</b></code></dd>
|
|
<dd><code><b>$</b></code></dd>
|
|
<dd><code><b>\</b></code> <code><b>b</b></code></dd>
|
|
<dd><code><b>\</b></code> <code><b>B</b></code></dd>
|
|
<dd><code><b>(</b></code> <code><b>?</b></code> <code><b>=</b></code> <i>Disjunction</i> <code><b>)</b></code></dd>
|
|
<dd><code><b>(</b></code> <code><b>?</b></code> <code><b>!</b></code> <i>Disjunction</i> <code><b>)</b></code></dd>
|
|
</dl>
|
|
<p>断言 <code><b>^</b></code> (行起始)匹配</p>
|
|
<div class="t-li1"><span class="t-li">1)</span> 立即后随<i>行终止符 (LineTerminator)</i> 字符的位置<span class="t-rev-inl t-until-cxx17"><span>(这可能不受支持)</span> <span><span class="t-mark-rev t-until-cxx17">(C++17 前)</span></span></span><span class="t-rev-inl t-since-cxx17"><span>(这仅若启用 <a href="cpp-regex-syntax_option_type.html"><tt>std::regex_constants::multiline</tt></a><span class="t-mark">(仅 C++)</span> 才得到保证)</span> <span><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></span></span></div>
|
|
<div class="t-li1"><span class="t-li">2)</span> 输入的起始(除非启用 <span class="t-lc"><a href="cpp-regex-match_flag_type.html">std::regex_constants::match_not_bol</a></span><span class="t-mark">(仅 C++)</span> )</div>
|
|
<p>断言 <code><b>$</b></code> (行结尾)匹配</p>
|
|
<div class="t-li1"><span class="t-li">1)</span> <i>行终止符</i>字符的位置<span class="t-rev-inl t-until-cxx17"><span>(这可能不受支持)</span> <span><span class="t-mark-rev t-until-cxx17">(C++17 前)</span></span></span><span class="t-rev-inl t-since-cxx17"><span>(这仅若启用 <a href="cpp-regex-syntax_option_type.html"><tt>std::regex_constants::multiline</tt></a><span class="t-mark">(仅 C++)</span> 才得到保证)</span> <span><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></span></span></div>
|
|
<div class="t-li1"><span class="t-li">2)</span> 输入的结尾(除非启用 <span class="t-lc"><a href="cpp-regex-match_flag_type.html">std::regex_constants::match_not_bol</a></span><span class="t-mark">(仅 C++)</span> )</div>
|
|
<p>上面二个断言和下面的原子 <code><b>.</b></code> 中,<i>行终止符</i>是下列四个字符之一: <code>U+000A</code> ( <code>\n</code> 或换行)、 <code>U+000D</code> ( <code>\r</code> 或回车)、 <code>U+2028</code> (行分隔符)或 <code>U+2029</code> (段分隔符)</p>
|
|
<p>断言 <code><b>\b</b></code> (词边界)匹配</p>
|
|
<div class="t-li1"><span class="t-li">1)</span> 词的起始(当前字符为字母、数字或下划线,而前一字符不是)</div>
|
|
<div class="t-li1"><span class="t-li">2)</span> 词的结尾(当前字符不是字母、数字或下划线,而前一字符是这些之一)</div>
|
|
<div class="t-li1"><span class="t-li">3)</span> 输入的起始,若首字符为字母、数字或下划线(除非启用 <span class="t-lc"><a href="cpp-regex-match_flag_type.html">std::regex_constants::match_not_bow</a></span><span class="t-mark">(仅 C++)</span> )</div>
|
|
<div class="t-li1"><span class="t-li">4)</span> 输入的结尾,若末字符为字母、数字或下划线(除非启用 <span class="t-lc"><a href="cpp-regex-match_flag_type.html">std::regex_constants::match_not_eow</a></span><span class="t-mark">(仅 C++)</span> )</div>
|
|
<p>断言 <code><b>\B</b></code> (反词边界)匹配所有字符,<b>除了</b>下列内容</p>
|
|
<div class="t-li1"><span class="t-li">1)</span> 词的起始(当前字符为字母、数字或下划线,而前一字符不是这些之一或不存在)</div>
|
|
<div class="t-li1"><span class="t-li">2)</span> 词的结尾(当前字符不是字母、数字或下划线(或匹配者在输入结尾),前一字符是这些之一)</div>
|
|
<p>若<i>析取</i>会匹配在当前位置的输入,则断言 <code><b>(</b></code> <code><b>?</b></code> <code><b>=</b></code> <i>析取</i> <code><b>)</b></code> (零宽正前瞻)匹配。</p>
|
|
<p>若<i>析取</i><b>不</b>会匹配在当前位置的的输入,则断言 <code><b>(</b></code> <code><b>?</b></code> <code><b>!</b></code> <i>析取</i> <code><b>)</b></code> (零宽负前瞻)匹配。</p>
|
|
<p>对于两个前瞻断言,在匹配<i>析取</i>时,不在匹配剩余正则表达式之前令位置前进。另外,若<i>析取</i>能以多种方式在当前位置匹配,则只尝试第一个。</p>
|
|
<p>ECMAScript 禁止回撤到前瞻析取中,这影响到来自剩余正则表达式的正前瞻中的回溯引用(见下方示例) 。到来自剩余正则表达式的负前瞻中的回溯引用始终没有定义(因为前瞻断言必定无法继续)。</p>
|
|
<p>注意:前瞻断言可用于创建多个正则表达式间的逻辑与(见下方示例)。</p>
|
|
<div class="t-example">
|
|
<div class="t-example-live-link"></div>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="co2">#include <iostream></span>
|
|
<span class="co2">#include <regex></span>
|
|
|
|
<span class="co1">// TODO :转换到接受宽字符序列</span>
|
|
<span class="co1">// std::match_results<std::basic_string<_ch>::const_iterator> m; 不行。</span>
|
|
<span class="kw4">void</span> show_matches<span class="br0">(</span><span class="kw4">const</span> <a href="cpp-string-basic_string.html"><span class="kw1230">std::<span class="me2">string</span></span></a><span class="sy3">&</span> in, <span class="kw4">const</span> <a href="cpp-string-basic_string.html"><span class="kw1230">std::<span class="me2">string</span></span></a><span class="sy3">&</span> re<span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<a href="cpp-regex-match_results.html"><span class="kw2010">std::<span class="me2">smatch</span></span></a> m<span class="sy4">;</span>
|
|
<a href="cpp-regex-regex_search.html"><span class="kw2013">std::<span class="me2">regex_search</span></span></a><span class="br0">(</span>in, m, <a href="cpp-regex-basic_regex.html"><span class="kw2000">std::<span class="me2">regex</span></span></a><span class="br0">(</span>re<span class="br0">)</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="kw1">if</span><span class="br0">(</span>m.<span class="me1">empty</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"input=["</span> <span class="sy1"><<</span> in <span class="sy1"><<</span> <span class="st0">"], regex=["</span> <span class="sy1"><<</span> re <span class="sy1"><<</span> <span class="st0">"]: NO MATCH<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
<span class="br0">}</span> <span class="kw1">else</span> <span class="br0">{</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"input=["</span> <span class="sy1"><<</span> in <span class="sy1"><<</span> <span class="st0">"], regex=["</span> <span class="sy1"><<</span> re <span class="sy1"><<</span> <span class="st0">"]: "</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"prefix=["</span> <span class="sy1"><<</span> m.<span class="me1">prefix</span><span class="br0">(</span><span class="br0">)</span> <span class="sy1"><<</span> <span class="st0">"] "</span><span class="sy4">;</span>
|
|
<span class="kw1">for</span><span class="br0">(</span><a href="cpp-types-size_t.html"><span class="kw100">std::<span class="me2">size_t</span></span></a> n <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span> n <span class="sy1"><</span> m.<span class="me1">size</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="sy2">++</span>n<span class="br0">)</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">" m["</span> <span class="sy1"><<</span> n <span class="sy1"><<</span> <span class="st0">"]=["</span> <span class="sy1"><<</span> m<span class="br0">[</span>n<span class="br0">]</span> <span class="sy1"><<</span> <span class="st0">"] "</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"suffix=["</span> <span class="sy1"><<</span> m.<span class="me1">suffix</span><span class="br0">(</span><span class="br0">)</span> <span class="sy1"><<</span> <span class="st0">"]<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
<span class="br0">}</span>
|
|
|
|
<span class="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="co1">// 在输入结尾匹配 a</span>
|
|
show_matches<span class="br0">(</span><span class="st0">"aaa"</span>, <span class="st0">"a$"</span><span class="br0">)</span><span class="sy4">;</span>
|
|
|
|
<span class="co1">// 在第一个词结尾匹配 o</span>
|
|
show_matches<span class="br0">(</span><span class="st0">"moo goo gai pan"</span>, <span class="st0">"o<span class="es1">\\</span>b"</span><span class="br0">)</span><span class="sy4">;</span>
|
|
|
|
<span class="co1">// 前瞻匹配立即在第一个 b 之后的空字符串</span>
|
|
<span class="co1">// 这以 "aaa" 填充 m[1] ,尽管 m[0] 为空</span>
|
|
show_matches<span class="br0">(</span><span class="st0">"baaabac"</span>, <span class="st0">"(?=(a+))"</span><span class="br0">)</span><span class="sy4">;</span>
|
|
|
|
<span class="co1">// 因为禁止回溯引用回撤到前瞻中,</span>
|
|
<span class="co1">// 这匹配 aba 而非 aaaba</span>
|
|
show_matches<span class="br0">(</span><span class="st0">"baaabac"</span>, <span class="st0">"(?=(a+))a*b<span class="es1">\\</span>1"</span><span class="br0">)</span><span class="sy4">;</span>
|
|
|
|
<span class="co1">// 经由前瞻的逻辑与:此密码匹配,若它含有</span>
|
|
<span class="co1">// 至少一个小写字母</span>
|
|
<span class="co1">// 与 至少一个大写字母</span>
|
|
<span class="co1">// 与 至少一个标点字符</span>
|
|
<span class="co1">// 与 至少有 6 个字符长</span>
|
|
show_matches<span class="br0">(</span><span class="st0">"abcdef"</span>, <span class="st0">"(?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:punct:]]).{6,}"</span><span class="br0">)</span><span class="sy4">;</span>
|
|
show_matches<span class="br0">(</span><span class="st0">"aB,def"</span>, <span class="st0">"(?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:punct:]]).{6,}"</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>输出:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="text source-text">
|
|
<pre class="de1">input=[aaa], regex=[a$]: prefix=[aa] m[0]=[a] suffix=[]
|
|
input=[moo goo gai pan], regex=[o\b]: prefix=[mo] m[0]=[o] suffix=[ goo gai pan]
|
|
input=[baaabac], regex=[(?=(a+))]: prefix=[b] m[0]=[] m[1]=[aaa] suffix=[aaabac]
|
|
input=[baaabac], regex=[(?=(a+))a*b\1]: prefix=[baa] m[0]=[aba] m[1]=[a] suffix=[c]
|
|
input=[abcdef], regex=[(?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:punct:]]).{6,}]:
|
|
NO MATCH
|
|
input=[aB,def], regex=[(?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:punct:]]).{6,}]:
|
|
prefix=[] m[0]=[aB,def] suffix=[]</pre></div>
|
|
</div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E5.8E.9F.E5.AD.90">原子</span></h3>
|
|
<p><i>原子</i>能为下列之一:</p>
|
|
<p><i>Atom</i> ::</p>
|
|
<dl>
|
|
<dd><i>PatternCharacter</i></dd>
|
|
<dd><code><b>.</b></code></dd>
|
|
<dd><code><b>\</b></code> <i>AtomEscape</i></dd>
|
|
<dd><i>CharacterClass</i></dd>
|
|
<dd><code><b>(</b></code> <i>Disjunction</i> <code><b>)</b></code></dd>
|
|
<dd><code><b>(</b></code> <code><b>?</b></code> <code><b>:</b></code> <i>Disjunction</i> <code><b>)</b></code></dd>
|
|
</dl>
|
|
<p>其中 <i>AtomEscape</i> ::</p>
|
|
<dl>
|
|
<dd><i>DecimalEscape</i></dd>
|
|
<dd><i>CharacterEscape</i></dd>
|
|
<dd><i>CharacterClassEscape</i></dd>
|
|
</dl>
|
|
<p>不同种类的原子求值方式不同。</p>
|
|
<h3><span class="mw-headline" id=".E5.AD.90.E8.A1.A8.E8.BE.BE.E5.BC.8F">子表达式</span></h3>
|
|
<p><i>原子</i> <code><b>(</b></code> <i>析取</i> <code><b>)</b></code> 是有标记表达式:它执行<i>析取</i>并存储<i>析取</i>所消耗的输入子串于子匹配数组,下标对应在此点已遇到的整个正则表达式中,有标记子表达式的左开括号 <code><b>(</b></code> 次数。</p>
|
|
<p>除了在 <span class="t-lc"><a href="cpp-regex-match_results.html">std::match_results</a></span> 中返回,捕获的子匹配还可作为回溯引用( <code>\1</code> 、 <code>\2</code> ……)访问,并在正则表达式中引用它们。注意 <span class="t-lc"><a href="cpp-regex-regex_replace.html">std::regex_replace</a></span> 以同 String.prototype.replace (ECMA-262, part 15.5.4.11) 的方式,对于回溯引用以 <code>$</code> 代替 <code>\</code> ( <code>$1</code> 、 <code>$2</code> ……)。</p>
|
|
<p><i>原子</i> <code><b>(</b></code> <code><b>?</b></code> <code><b>:</b></code> <i>析取</i> <code><b>)</b></code> (非标记子表达式)简单地求值 <i>析取</i> 并不存储其结果于子匹配。这单纯是词法分组。</p>
|
|
<table class="metadata plainlinks ambox mbox-small-left ambox-notice" style="">
|
|
<tr>
|
|
<td class="mbox-empty-cell"></td>
|
|
<td class="mbox-text" style="">本节未完成<br />
|
|
原因:暂无示例</td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E5.9B.9E.E6.BA.AF.E5.BC.95.E7.94.A8">回溯引用</span></h3>
|
|
<p><i>DecimalEscape</i> ::</p>
|
|
<dl>
|
|
<dd><i>DecimalIntegerLiteral</i> [<i>lookahead</i> ∉ <i>DecimalDigit</i>]</dd>
|
|
</dl>
|
|
<p>若 <code><b>\</b></code> 后随首位非 <code>0</code> 的十进制数 <code>N</code> ,则认为该转义序列为<i>回溯引用 (backreference)</i> 。通过在每个数位上调用 <span class="t-lc"><a href="cpp-regex-regex_traits-value.html">std::regex_traits::value</a></span><span class="t-mark">(仅 C++)</span> 并用底 10 算术组合及其结果获得 <code>N</code> 。若 <code>N</code> 大于整个正则表达式中捕获括号的总数,则为错误。</p>
|
|
<p>回溯引用 <code>\N</code> 作为原子出现时,它匹配当前存储于子匹配数组中第 N 个元素的子串。</p>
|
|
<p>十进制转义 <code>\0</code> <b>不</b>是回溯引用:它是表示空字符的字符转义。它不能为十进制数所后随。</p>
|
|
<p>如上,注意 <span class="t-lc"><a href="cpp-regex-regex_replace.html">std::regex_replace</a></span> 对于回溯引用以 <code>$</code> 代替 <code>\</code> ( <code>$1</code> 、 <code>$2</code> ……)。</p>
|
|
<table class="metadata plainlinks ambox mbox-small-left ambox-notice" style="">
|
|
<tr>
|
|
<td class="mbox-empty-cell"></td>
|
|
<td class="mbox-text" style="">本节未完成<br />
|
|
原因:暂无示例</td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E5.8D.95.E5.AD.97.E7.AC.A6.E5.8C.B9.E9.85.8D">单字符匹配</span></h3>
|
|
<p><i>原子</i> <code><b>.</b></code> 匹配并消耗来自输入序列的任一字符,除了<i>行终止符</i>( <code>U+000A</code> 、 <code>U+000D</code> 、 <code>U+2028</code> 或 <code>U+2029</code> )</p>
|
|
<p><i>原子</i> <i>模式字符</i> ,其中<i>模式字符 (PatternCharacter)</i> 为任何<i>源字符 (SourceCharacter)</i> ,<b>除了</b>字符 <code><b>^ $ \ . * + ? ( ) [ ] { } |</b></code> ,匹配并消耗一个来自输入的字符,若它等于此<i>模式字符</i>。</p>
|
|
<p>这个及所有其他单字符匹配定义如下:</p>
|
|
<div class="t-li1"><span class="t-li">1)</span> 若设置了 <span class="t-lc"><a href="cpp-regex-syntax_option_type.html">std::regex_constants::icase</a></span> ,则若 <span class="t-lc"><a href="cpp-regex-regex_traits-translate_nocase.html">std::regex_traits::translate_nocase</a></span> 的返回值相等则字符相等。<span class="t-mark">(仅 C++)</span></div>
|
|
<div class="t-li1"><span class="t-li">2)</span> 否则,若设置了 <span class="t-lc"><a href="cpp-regex-syntax_option_type.html">std::regex_constants::collate</a></span> ,则若 <span class="t-lc"><a href="cpp-regex-regex_traits-translate.html">std::regex_traits::translate</a></span> 的返回值相等则字符相等。<span class="t-mark">(仅 C++)</span></div>
|
|
<div class="t-li1"><span class="t-li">3)</span> 否则,若 operator== 返回 true 则字符相等。</div>
|
|
<p>每个由转义字符 <code><b>\</b></code> 后随<i>字符转义 (CharacterEscape)</i> 的<i>原子</i>,还有特殊十进制转义 <code><b>\0</b></code> ,匹配消耗一个来自输入的字符,若它等于<i>字符转义</i>所表示的字符。辨识下列字符转义序列:</p>
|
|
<p><i>CharacterEscape</i> ::</p>
|
|
<dl>
|
|
<dd><i>ControlEscape</i></dd>
|
|
<dd><code><b>c</b></code> <i>ControlLetter</i></dd>
|
|
<dd><i>HexEscapeSequence</i></dd>
|
|
<dd><i>UnicodeEscapeSequence</i></dd>
|
|
<dd><i>IdentityEscape</i></dd>
|
|
</dl>
|
|
<p>此处<i>控制转义 (ControlEscape)</i> 为下列五个字符之一: <code><b>f n r t v</b></code></p>
|
|
<table class="wikitable">
|
|
<tr>
|
|
<th>控制转义</th>
|
|
<th>编码单元</th>
|
|
<th>名称</th>
|
|
</tr>
|
|
<tr>
|
|
<td><code><b>f</b></code></td>
|
|
<td>U+000C</td>
|
|
<td>换页</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code><b>n</b></code></td>
|
|
<td>U+000A</td>
|
|
<td>换行</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code><b>r</b></code></td>
|
|
<td>U+000D</td>
|
|
<td>回车</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code><b>t</b></code></td>
|
|
<td>U+0009</td>
|
|
<td>水平制表</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code><b>v</b></code></td>
|
|
<td>U+000B</td>
|
|
<td>垂直制表</td>
|
|
</tr>
|
|
</table>
|
|
<p><i>控制字母 (ControlLetter)</i> 为任何小写或大写 ASCII 字符,而此字符转义所匹配字符的编码单元等于<i>控制字母</i>的编码单元的值除以 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="nu0">32</span></span></span> ,例如 <code><b>\cD</b></code> 和 <code><b>\cd</b></code> 都匹配编码单元 <code>U+0004</code> (EOT) ,因为 'D' 是 <code>U+0044</code> 而 <code>0x44 % 32 == 4</code> 并且 'd' 是 <code>U+0064</code> 而 <code>0x64 % 32 == 4</code> 。</p>
|
|
<p><i>十六进制转义序列 (HexEscapeSequence)</i> 是字母 <code><b>x</b></code> 后随准确二个<i>十六进制位 (HexDigit)</i> (其中<i>十六进制位</i>是 <code><b>0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F</b></code> 之一)。此字符转义所匹配字符的编码单元等于二位十六进制数的数值。</p>
|
|
<p><i>Unicode转义序列 (UnicodeEscapeSequence)</i> 是字母 <code><b>u</b></code> 后随准确四个<i>十六进制位</i>。此字符转义所匹配字符的编码单元等于此四位十六进制数的数值。若该值不适于此 <span class="t-lc"><a href="cpp-regex-basic_regex.html">std::basic_regex</a></span> 的 CharT ,则抛出 <span class="t-lc"><a href="cpp-regex-regex_error.html">std::regex_error</a></span> <span class="t-mark">(仅 C++)</span>。</p>
|
|
<p><i>自身转义 (IdentityEscape)</i> 能为任何非字母数字的字符:例如另一反斜杠。它照原样匹配字符。</p>
|
|
<div class="t-example">
|
|
<div class="t-example-live-link"></div>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="co2">#include <iostream></span>
|
|
<span class="co2">#include <regex></span>
|
|
|
|
<span class="co1">// TODO :转换到接受宽字符序列</span>
|
|
<span class="co1">// std::match_results<std::basic_string<_ch>::const_iterator> m; 不行。</span>
|
|
<span class="kw4">void</span> show_matches<span class="br0">(</span><span class="kw4">const</span> <a href="cpp-string-basic_string.html"><span class="kw1230">std::<span class="me2">string</span></span></a><span class="sy3">&</span> in, <span class="kw4">const</span> <a href="cpp-string-basic_string.html"><span class="kw1230">std::<span class="me2">string</span></span></a><span class="sy3">&</span> re<span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<a href="cpp-regex-match_results.html"><span class="kw2010">std::<span class="me2">smatch</span></span></a> m<span class="sy4">;</span>
|
|
<a href="cpp-regex-regex_search.html"><span class="kw2013">std::<span class="me2">regex_search</span></span></a><span class="br0">(</span>in, m, <a href="cpp-regex-basic_regex.html"><span class="kw2000">std::<span class="me2">regex</span></span></a><span class="br0">(</span>re<span class="br0">)</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="kw1">if</span><span class="br0">(</span>m.<span class="me1">empty</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"input=["</span> <span class="sy1"><<</span> in <span class="sy1"><<</span> <span class="st0">"], regex=["</span> <span class="sy1"><<</span> re <span class="sy1"><<</span> <span class="st0">"]: NO MATCH<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
<span class="br0">}</span> <span class="kw1">else</span> <span class="br0">{</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"input=["</span> <span class="sy1"><<</span> in <span class="sy1"><<</span> <span class="st0">"], regex=["</span> <span class="sy1"><<</span> re <span class="sy1"><<</span> <span class="st0">"]: "</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"prefix=["</span> <span class="sy1"><<</span> m.<span class="me1">prefix</span><span class="br0">(</span><span class="br0">)</span> <span class="sy1"><<</span> <span class="st0">"] "</span><span class="sy4">;</span>
|
|
<span class="kw1">for</span><span class="br0">(</span><a href="cpp-types-size_t.html"><span class="kw100">std::<span class="me2">size_t</span></span></a> n <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span> n <span class="sy1"><</span> m.<span class="me1">size</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="sy2">++</span>n<span class="br0">)</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">" m["</span> <span class="sy1"><<</span> n <span class="sy1"><<</span> <span class="st0">"]=["</span> <span class="sy1"><<</span> m<span class="br0">[</span>n<span class="br0">]</span> <span class="sy1"><<</span> <span class="st0">"] "</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"suffix=["</span> <span class="sy1"><<</span> m.<span class="me1">suffix</span><span class="br0">(</span><span class="br0">)</span> <span class="sy1"><<</span> <span class="st0">"]<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
<span class="br0">}</span>
|
|
|
|
<span class="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="co1">// 大多数转义类似 C++ ,为元字符保存。你将需要在斜杠情形使用双重转义或未处理字符串。</span>
|
|
show_matches<span class="br0">(</span><span class="st0">"C++<span class="es1">\\</span>"</span>, R<span class="st0">"(C\+\+<span class="es1">\\</span>)"</span><span class="br0">)</span><span class="sy4">;</span>
|
|
|
|
<span class="co1">// 转义序列与 NUL 。</span>
|
|
<a href="cpp-string-basic_string.html"><span class="kw1230">std::<span class="me2">string</span></span></a> s<span class="br0">(</span><span class="st0">"ab<span class="es2">\xff</span><span class="es5">\0</span>cd"</span>, <span class="nu0">5</span><span class="br0">)</span><span class="sy4">;</span>
|
|
show_matches<span class="br0">(</span>s, <span class="st0">"(<span class="es1">\\</span>0|<span class="es1">\\</span>u00ff)"</span><span class="br0">)</span><span class="sy4">;</span>
|
|
|
|
<span class="co1">// 没有定义非 BMP Unicode 的匹配,因为 ECMAScript 使用 UTF-16 原子。</span>
|
|
<span class="co1">// 此 emoji 香蕉是否匹配能为平台依赖:</span>
|
|
<span class="co1">// XXX :这些需要为宽字符串!</span>
|
|
<span class="co1">// show_matches(L"\U0001f34c", L"[\\u0000-\\ufffe]+");</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E5.AD.97.E7.AC.A6.E7.B1.BB">字符类</span></h3>
|
|
<p>原子能表示字符类,即它会匹配并消耗一个字符,若该字符属于预定义的字符组之一。</p>
|
|
<p>字符类能通过字符类转义引入:</p>
|
|
<p><i>Atom</i> ::</p>
|
|
<dl>
|
|
<dd><code><b>\</b></code> <i>CharacterClassEscape</i></dd>
|
|
</dl>
|
|
<p>或直接为</p>
|
|
<p><i>Atom</i> ::</p>
|
|
<dl>
|
|
<dd><i>CharacterClass</i></dd>
|
|
</dl>
|
|
<p>字符类转义是一些常用字符类的简洁写法,如下:</p>
|
|
<table class="wikitable">
|
|
<tr>
|
|
<th>字符类转义</th>
|
|
<th>类名表达式<span class="t-mark">(仅 C++)</span></th>
|
|
<th>含义</th>
|
|
</tr>
|
|
<tr>
|
|
<td><code><b>d</b></code></td>
|
|
<td><code><b>[[:digit:]]</b></code></td>
|
|
<td>数字</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code><b>D</b></code></td>
|
|
<td><code><b>[^[:digit:]]</b></code></td>
|
|
<td>非数字</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code><b>s</b></code></td>
|
|
<td><code><b>[[:space:]]</b></code></td>
|
|
<td>空白字符</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code><b>S</b></code></td>
|
|
<td><code><b>[^[:space:]]</b></code></td>
|
|
<td>非空白字符</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code><b>w</b></code></td>
|
|
<td><code><b>[_[:alnum:]]</b></code></td>
|
|
<td>字母数字字符及字符 <code><b>_</b></code></td>
|
|
</tr>
|
|
<tr>
|
|
<td><code><b>W</b></code></td>
|
|
<td><code><b>[^_[:alnum:]]</b></code></td>
|
|
<td>异于字母数字或 <code><b>_</b></code> 的字符</td>
|
|
</tr>
|
|
</table>
|
|
<span style="font-size:0.7em; line-height:130%">C++ 中这些字符类转义的准确含义以依赖 locale 的具名字符类定义,而非通过显式列举同 ECMAScript 中的可接受字符。</span>
|
|
<p><i>字符类 (CharacterClass)</i> 是方括号环绕的<i>类范围 (ClassRanges)</i> 序列,可选地以取反运算符 <code><b>^</b></code> 开始。若它始于 <code><b>^</b></code> ,则此<i>原子</i>匹配任何<b>不在</b>所有<i>类范围</i>的并所表示的字符集合中的字符。否则,此<i>原子</i>匹配任何<b>在</b>所有<i>类范围</i>的并所表示的字符集合中的字符。</p>
|
|
<p><i>CharacterClass</i> ::</p>
|
|
<dl>
|
|
<dd><code><b>[</b></code> <code><b>[</b></code> <i>lookahead ∉ {</i><code><b>^</b></code><i>}]</i> <i>ClassRanges</i> <code><b>]</b></code></dd>
|
|
<dd><code><b>[</b></code> <code><b>^</b></code> <i>ClassRanges</i> <code><b>]</b></code></dd>
|
|
</dl>
|
|
<p>ClassRanges ::</p>
|
|
<dl>
|
|
<dd>[empty]</dd>
|
|
<dd><i>NonemptyClassRanges</i></dd>
|
|
</dl>
|
|
<p><i>NonemptyClassRanges</i> ::</p>
|
|
<dl>
|
|
<dd><i>ClassAtom</i></dd>
|
|
<dd><i>ClassAtom</i> <i>NonemptyClassRangesNoDash</i></dd>
|
|
<dd><i>ClassAtom</i> - <i>ClassAtom</i> <i>ClassRanges</i></dd>
|
|
</dl>
|
|
<p>若非空类范围拥有形式 <code><b><i>ClassAtom</i> - <i>ClassAtom</i></b></code> ,则它匹配来自定义如下的范围的任何字符:<span class="t-mark">(仅 C++)</span></p>
|
|
<p>首个<i>类原子 (ClassAtom)</i> 必须匹配单个对照元素 <code>c1</code> ,而第二个<i>类原子</i>必须匹配单个对照元素 <code>c2</code> 。采用下列步骤,测试此范围是否匹配输入字符 <code>c</code> :</p>
|
|
<div class="t-li1"><span class="t-li">1)</span> 若 <span class="t-lc"><a href="cpp-regex-syntax_option_type.html">std::regex_constants::collate</a></span> 不打开,则通过直接比较编码点匹配字符:若 <code>c1 <= c && c <= c2</code> 则匹配 <code>c</code></div>
|
|
<div class="t-li1"><span class="t-li">1)</span> 否则(若启用 <span class="t-lc"><a href="cpp-regex-syntax_option_type.html">std::regex_constants::collate</a></span> ):</div>
|
|
<div class="t-li2"><span class="t-li">1)</span> 若启用 <span class="t-lc"><a href="cpp-regex-syntax_option_type.html">std::regex_constants::icase</a></span> ,则传递所有三个字符( <code>c</code> 、 <code>c1</code> 及 <code>c2</code> )给 <span class="t-lc"><a href="cpp-regex-regex_traits-translate_nocase.html">std::regex_traits::translate_nocase</a></span></div>
|
|
<div class="t-li2"><span class="t-li">2)</span> 否则(若未设置 <span class="t-lc"><a href="cpp-regex-syntax_option_type.html">std::regex_constants::icase</a></span> ),则传递所有三个字符( <code>c</code> 、 <code>c1</code> 及 <code>c2</code> )给 <span class="t-lc"><a href="cpp-regex-regex_traits-translate.html">std::regex_traits::translate</a></span></div>
|
|
<div class="t-li1"><span class="t-li">2)</span> 用 <span class="t-lc"><a href="cpp-regex-regex_traits-transform.html">std::regex_traits::transform</a></span> 比较结果字符串,而若 <code>transformed c1 <= transformed c && transformed c <= transformed c2</code> 则匹配 <code>c</code></div>
|
|
<p>按字面对待字符 <code><b>-</b></code> ,若它是下列之一</p>
|
|
<ul>
|
|
<li><i>类范围</i>的首或末字符</li>
|
|
<li>杠分隔范围规定的开始或结尾类原子</li>
|
|
<li>立即在杠分隔范围规定之后。</li>
|
|
<li>以反斜杠转义为<i>字符转义</i></li>
|
|
</ul>
|
|
<p>NonemptyClassRangesNoDash ::</p>
|
|
<dl>
|
|
<dd><i>ClassAtom</i></dd>
|
|
<dd><i>ClassAtomNoDash</i> <i>NonemptyClassRangesNoDash</i></dd>
|
|
<dd><i>ClassAtomNoDash</i> - <i>ClassAtom</i> <i>ClassRanges</i></dd>
|
|
</dl>
|
|
<p><i>ClassAtom</i> ::</p>
|
|
<dl>
|
|
<dd><code><b>-</b></code></dd>
|
|
<dd><i>ClassAtomNoDash</i></dd>
|
|
<dd><i>ClassAtomExClass</i><span class="t-mark">(仅 C++)</span></dd>
|
|
<dd><i>ClassAtomCollatingElement</i><span class="t-mark">(仅 C++)</span></dd>
|
|
<dd><i>ClassAtomEquivalence</i><span class="t-mark">(仅 C++)</span></dd>
|
|
</dl>
|
|
<p>ClassAtomNoDash ::</p>
|
|
<dl>
|
|
<dd><i>SourceCharacter</i> but not one of <code><b>\ or ] or -</b></code></dd>
|
|
<dd><code><b>\</b></code> <i>ClassEscape</i></dd>
|
|
</dl>
|
|
<p>每个<i>无杠类原子 (ClassAtomNoDash)</i> 表示单个字符——原状的<i>源字符</i>或转义如下的字符:</p>
|
|
<p>ClassEscape ::</p>
|
|
<dl>
|
|
<dd><i>DecimalEscape</i></dd>
|
|
<dd><code><b>b</b></code></dd>
|
|
<dd><i>CharacterEscape</i></dd>
|
|
<dd><i>CharacterClassEscape</i></dd>
|
|
</dl>
|
|
<p>特殊的<i>类转义 (ClassEscape)</i> <code><b>\b</b></code> 产生匹配编码单元 U+0008 (退格)的字符集。在<i>字符类</i>外,它是词边界<i>断言</i>。</p>
|
|
<p><i>字符类</i>内, <code><b>\B</b></code> 的使用和任何回溯引用(异于零的<i>十进制转义</i>)都是错误。</p>
|
|
<p>为将字符 <code><b>-</b></code> 和 <code><b>]</b></code> 当做原子,一些情形中需要转义它们。其他拥有在<i>字符类</i>外的特殊含义的字符,例如 <code><b>*</b></code> 或 <code><b>?</b></code> ,不需要转义。</p>
|
|
<table class="metadata plainlinks ambox mbox-small-left ambox-notice" style="">
|
|
<tr>
|
|
<td class="mbox-empty-cell"></td>
|
|
<td class="mbox-text" style="">本节未完成<br />
|
|
原因:暂无示例</td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E5.9F.BA.E4.BA.8E_POSIX_.E7.9A.84.E5.AD.97.E7.AC.A6.E7.B1.BB">基于 POSIX 的字符类</span></h3>
|
|
<p>这些字符类是对 ECMAScript 文法的扩展,并等价于 POSIX 正则表达式中找到的字符类。</p>
|
|
<p>ClassAtomExClass<span class="t-mark">(仅 C++)</span> ::</p>
|
|
<dl>
|
|
<dd><code><b>[:</b></code> <i>ClassName</i> <code><b>:]</b></code></dd>
|
|
</dl>
|
|
<p>表示所有具名字符类<i>类名 (ClassName)</i> 中的成员。仅若 <span class="t-lc"><a href="cpp-regex-regex_traits-lookup_classname.html">std::regex_traits::lookup_classname</a></span> 对此名称返回非零字符串,名称才合法。如 <span class="t-lc"><a href="cpp-regex-regex_traits-lookup_classname.html">std::regex_traits::lookup_classname</a></span> 中描述,保证辨识下列名称: <code><b>alnum, alpha, blank, cntrl, digit, graph, lower, print, punct, space, upper, xdigit, d, s, w</b></code> 。额外的名称(如日文中的 <code><b>jdigit</b></code> 或 <code><b>jkanji</b></code> )可为系统提供的 locale 提供,或实现为用户定义的扩展:</p>
|
|
<p>ClassAtomCollatingElement<span class="t-mark">(仅 C++)</span> ::</p>
|
|
<dl>
|
|
<dd><code><b>[.</b></code> <i>ClassName</i> <code><b>.]</b></code></dd>
|
|
</dl>
|
|
<p>表示具名对照元素,它可表示单个字符,或在感染的 locale 下作为单个单位对照的字符序列,例如 <code>[.tilde.]</code> 或捷克文中的 <code>[.ch.]</code> 。仅若 <span class="t-lc"><a href="cpp-regex-regex_traits-lookup_collatename.html">std::regex_traits::lookup_collatename</a></span> 不是空字符串名称才合法。</p>
|
|
<p>使用 <span class="t-lc"><a href="cpp-regex-syntax_option_type.html">std::regex_constants::collate</a></span> 时,始终能以对照元素为范围的端点(例如匈牙利文中的 <code>[[.dz.]-g]</code> )。</p>
|
|
<p>ClassAtomEquivalence<span class="t-mark">(仅 C++)</span> ::</p>
|
|
<dl>
|
|
<dd><code><b>[=</b></code> <i>ClassName</i> <code><b>=]</b></code></dd>
|
|
</dl>
|
|
<p>表示与具名对照元素相同的等价类的所有成员字符,即其初等对照关键与对照元素<i>类名</i>所拥有者相同的字符。仅若 <span class="t-lc"><a href="cpp-regex-regex_traits-lookup_collatename.html">std::regex_traits::lookup_collatename</a></span> 对该名称返回非空字符串,且 <span class="t-lc"><a href="cpp-regex-regex_traits-transform_primary.html">std::regex_traits::transform_primary</a></span> 对调用 <span class="t-lc"><a href="cpp-regex-regex_traits-lookup_collatename.html">std::regex_traits::lookup_collatename</a></span> 的结果的返回值不是空字符串,名称才合法。</p>
|
|
<p>初等排序关键是忽略大小写、标音符或本地环境限定裁剪的关键;故例如 <code>[[=a=]]</code> 匹配任何这些字符之一: <code>a, À, Á, Â, Ã, Ä, Å, A, à, á, â, ã, ä</code> 和 <code>å</code> 。</p>
|
|
<p>ClassName<span class="t-mark">(仅 C++)</span> ::</p>
|
|
<dl>
|
|
<dd>ClassNameCharacter</dd>
|
|
<dd>ClassNameCharacter ClassName</dd>
|
|
</dl>
|
|
<p>ClassNameCharacter<span class="t-mark">(仅 C++)</span> ::</p>
|
|
<dl>
|
|
<dd><i>SourceCharacter</i> 但非 <code><b>. = :</b></code> 之一</dd>
|
|
</dl>
|
|
<table class="metadata plainlinks ambox mbox-small-left ambox-notice" style="">
|
|
<tr>
|
|
<td class="mbox-empty-cell"></td>
|
|
<td class="mbox-text" style="">本节未完成<br />
|
|
原因:暂无示例</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="visualClear"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|