使用Python和正则表达式在字符串中查找C关键字

使用Python和正则表达式在字符串中查找C关键字,python,regex,Python,Regex,我试图找到并打印字符串中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.sta

我试图找到并打印字符串中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”。为什么会这样?

首先,Python不使用正斜杠(
/
)来指示正则表达式模式的开始和结束。按照惯例,将使用原始字符串。原始字符串是避免字符串中特殊字符编码的一种方法。最常见的示例是换行符(
'\n'
)。通常这两个字符会被转换成一个特殊的换行符,但是如果我们想要一个正斜杠加上一个n,我们就使用一个原始字符串,比如
r'\n'
。或者,我们可以对反斜杠字符进行转义,并将其写成
'\\n'
,但是对于包含更多特殊字符的较长字符串,我们确实希望避免在任何地方都使用反斜杠。您可能注意到,原始字符串是编写正则表达式的一种非常方便的方法

您忘记将模式设置为原始字符串,因此\b被解释为特殊转义字符(在本例中,无论出于何种原因,它都被转换为ASCII字符#8,但不确定原因),而不是单词边界。通过在字符串前面加上
r
,可以将任何字符串文字设置为原始字符串:

>>> re.findall('\bint|void|return\b', 'int main( void )\n{\nreturn 0;\n}')
['void']
>>> re.findall(r'\bint|void|return\b', 'int main( void )\n{\nreturn 0;\n}')
['int', 'void', 'return']
一,。Python不会在
/
中包含模式:

pattern = '\bint|void|return\b' # still wrong
二,。您确实希望将其设置为原始字符串,否则
\b
将被解释为控制字符:

pattern = r'\bint|void|return\b' # still wrong
三,。您需要将您的或组括在括号中:

pattern = r'\b(int|void|return)\b' # yay
然后:

re.compile(pattern).findall(code)
# ['int', 'void', 'return']
在您最初的模式中,整个内容被划分为三个独立的部分:
/\bint
void
,以及
return\b/
,因此它自然只能找到
void

以下是一个示例:

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

输出相同,但更容易添加单词。

谢谢。我添加了r前缀,但仍然得到相同的结果。@FernandoKarpinski啊,对不起,我错过了字符串中的两个前斜杠。我已经编辑了我的答案。如果它总是
int return为什么不简单地匹配字符串
code.find('int')
…您仍然希望保留单词边界条件。
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