<p>我想它终于“点击”了,正是你在这里问的。看看下面:</p>
<pre><code>import re
smiley_pattern = '^(:\(|:\))+$' # matches only the smileys ":)" and ":("
def test_match(s):
print 'Value: %s; Result: %s' % (
s,
'Matches!' if re.match(smiley_pattern, s) else 'Doesn\'t match.'
)
should_match = [
':)', # Single smile
':(', # Single frown
':):)', # Two smiles
':(:(', # Two frowns
':):(', # Mix of a smile and a frown
]
should_not_match = [
'', # Empty string
':(foo', # Extraneous characters appended
'foo:(', # Extraneous characters prepended
':( :(', # Space between frowns
':( (', # Extraneous characters and space appended
':((' # Extraneous duplicate of final character appended
]
print('The following should all match:')
for x in should_match: test_match(x);
print('') # Newline for output clarity
print('The following should all not match:')
for x in should_not_match: test_match(x);
</code></pre>
<p>原始代码的问题在于regex是错误的:<code>(:\()</code>。让我们把它分解。</p>
<p>外括号是一个“分组”。如果要进行字符串替换,则需要引用它们,并用于同时对字符组应用正则表达式运算符。所以,你真的是在说:</p>
<ul>
<li><code>(</code>开始一个组
<ul>
<li><code>:\(</code>。。。做正则表达式的事情。。。</li>
</ul></li>
<li>“)”结束组</li>
</ul>
<p><code>:</code>不是regex保留字符,所以它只是一个冒号。<code>\</code>是,它的意思是“以下字符是文本字符,而不是正则表达式运算符”。这被称为“转义序列”。完全解析为英语,你的regex说</p>
<ul>
<li><code>(</code>开始一个组
<ul>
<li><code>:</code>结肠特征</li>
<li><code>\(</code>左括号字符</li>
</ul></li>
<li><code>)</code>结束组</li>
</ul>
<p>我使用的regex稍微复杂一些,但还不错。让我们把它分解成:<code>^(:\(|:\))+$</code>。</p>
<p><code>^</code>和<code>$</code>分别表示“行的开始”和“行的结束”。现在我们有。。。</p>
<ul>
<li><code>^</code>行首
<ul>
<li><code>(:\(|:\))+</code>。。。做正则表达式的事情。。。</li>
</ul></li>
<li><code>$</code>行尾</li>
</ul>
<p>。。。所以它只匹配组成整行的内容,而不是简单地出现在字符串的中间。</p>
<p>我们知道<code>(</code>和<code>)</code>表示一个分组。<code>+</code>表示“其中一个”。现在我们有:</p>
<ul>
<li><code>^</code>行首</li>
<li><code>(</code>启动组
<ul>
<li><code>:\(|:\)</code>。。。做正则表达式的事情。。。</li>
</ul></li>
<li><code>)</code>结束组</li>
<li><code>+</code>匹配一个或多个</li>
<li><code>$</code>行尾</li>
</ul>
<p>最后是<code>|</code>(管道)操作符。意思是“或”。因此,应用上面关于转义字符的知识,我们可以完成转换:</p>
<ul>
<li><code>^</code>行首</li>
<li><code>(</code>启动组
<ul>
<li><code>:</code>结肠特征</li>
<li><code>\(</code>左括号字符</li>
</ul></li>
<li><code>|</code>或
<ul>
<li><code>:</code>结肠特征</li>
<li><code>\)</code>右括号字符</li>
</ul></li>
<li><code>)</code>结束组</li>
<li><code>+</code>匹配一个或多个</li>
<li><code>$</code>行尾</li>
</ul>
<p>我希望这能有帮助。如果没有,请让我知道,我很乐意修改我的答复。</p>