我试图在字符串中找到并打印C关键字的开头和结尾索引
code = 'int main( void )\n{\nreturn 0;\n}'
这是我到目前为止所拥有的:
pattern = '/\bint|void|return\b/'
temp = re.compile( pattern )
for result in temp.finditer( code ):
print 'Found %s from %d to %d.' % ( result.group(), result.start(), result.end() )
但是,只找到' void' 。那是为什么?
答案 0 :(得分:2)
首先,Python不使用正斜杠(htmlspecialchars()
)来指示正则表达式模式的开始和结束。按照惯例,使用原始字符串代替。原始字符串是一种避免字符串中特殊字符编码的方法。最常见的示例是换行符(/
)。通常这两个字符将转换为单个特殊换行符,但是如果我们想要一个 literal 正斜杠后跟一个 literal n,我们使用像{{一样的原始字符串1}}。或者,我们可以转义反斜杠字符并将其写为'\n'
,但对于具有更多特殊字符的较长字符串,我们确实希望避免在任何地方抛出反斜杠。您可能会注意到,原始字符串是编写正则表达式的一种非常方便的方法。
您忘了将您的模式设为原始字符串,因此\ b被解释为特殊的转义字符(在这种情况下,无论出于何种原因,它都会转换为ASCII字符#8,而不是确定原因)而不是字边界。您可以通过在字符串前面添加r'\n'
来使任何字符串文字成为原始字符串:
'\\n'
答案 1 :(得分:2)
pattern = '/\bint|void|return\b/' # wrong
1。 Python并没有将模式包含在/
:
pattern = '\bint|void|return\b' # still wrong
2。你真的想把它变成一个原始字符串,否则\b
被解释为一个控制字符:
pattern = r'\bint|void|return\b' # still wrong
3。您需要将您的or-group括在括号中:
pattern = r'\b(int|void|return)\b' # yay
然后:
re.compile(pattern).findall(code)
# ['int', 'void', 'return']
在你的原始模式中,整个事物被解释为三个独立的部分:
/\bint
,void
和return\b/
,因此自然只找到void
。
答案 2 :(得分:2)
以下是一个例子:
src='''\
int main( void )
{
return 0;
}
'''
import re
for key, span in ((m.group(1), m.span(1)) for m in re.finditer(r'\b(int|main|void|return)\b', src)):
print key, span
打印:
int (0, 3)
main (4, 8)
void (10, 14)
return (28, 34)
但我认为使用一组关键字来验证找到的单词比使用模式中的所有单词更好。
考虑:
keywords={'int', 'main', 'void', 'return'}
for key, span in ((m.group(1), m.span(1)) for m in re.finditer(r'\b(\w+)\b', src)
if m.group(1) in keywords):
print key, span
输出相同,但更容易添加单词。