Python - 如何使用非字母字符拆分字符串

时间:2016-02-05 18:41:42

标签: python regex string parsing

我试图使用python来解析c ++源代码行。我唯一感兴趣的是包含指令。

    #include "header.hpp"

我希望它具有灵活性,并且仍然可以使用不良的编码风格,例如:

          #   include"header.hpp"  

我已经到了可以读取#和#之前和之后的空格的点。但是我仍然需要通过读取字符串找出它是什么指令,直到遇到非字母字符,无论天气如何,它都是空格,引号,制表符或有角度的括号。

所以基本上我的问题是:如何分割以alpha开头的字符串,直到遇到非alpha?

我想我可以用正则表达式做到这一点,但我在文档中找不到任何我想要的东西。

此外,如果有人就如何在引号或斜角括号内获得文件名提出建议,那将是一个加号。

8 个答案:

答案 0 :(得分:17)

您使用正则表达式的直觉是正确的。

import re
re.split('[^a-zA-Z]', string_to_split)

[^a-zA-Z]部分表示"不是字母字符"。

答案 1 :(得分:4)

你可以用正则表达式做到这一点。但是,您也可以使用简单的while循环。

def splitnonalpha(s):
   pos = 1
   while pos < len(s) and s[pos].isalpha():
      pos+=1
   return (s[:pos], s[pos:])

测试:

>>> splitnonalpha('#include"blah.hpp"')
('#include', '"blah.hpp"')

答案 2 :(得分:4)

我认为其他人提到的两个选项是re.splitre.findall

>>> import re
>>> re.split(r'\W+', '#include "header.hpp"')
['', 'include', 'header', 'hpp', '']
>>> re.findall(r'\w+', '#include "header.hpp"')
['include', 'header', 'hpp']

快速基准:

>>> setup = "import re; word_pattern = re.compile(r'\w+'); sep_pattern = re.compile(r'\W+')"
>>> iterations = 10**6
>>> timeit.timeit("re.findall(r'\w+', '#header foo bar!')", setup=setup, number=iterations)
3.000092029571533
>>> timeit.timeit("word_pattern.findall('#header foo bar!')", setup=setup, number=iterations)
1.5247418880462646
>>> timeit.timeit("re.split(r'\W+', '#header foo bar!')", setup=setup, number=iterations)
3.786440134048462
>>> timeit.timeit("sep_pattern.split('#header foo bar!')", setup=setup, number=iterations)
2.256173849105835

功能差异是re.split保留空标记。这对于标记化目的通常没用,但以下内容应与re.findall解决方案相同:

>>> filter(bool, re.split(r'\W+', '#include "header.hpp"'))
['include', 'header', 'hpp']

答案 3 :(得分:2)

您可以使用正则表达式。 \W令牌将匹配所有非单词字符(与非字母数字字符大致相同)。单词字符为A-Za-z0-9_。如果你想匹配下划线,你也可以[\W_]

>>> import re
>>> line = '#   include"header.hpp"  ' 
>>> m = re.match(r'^\s*#\s*include\W+([\w\.]+)\W*$', line)
>>> m.group(1)
'header.hpp'

答案 4 :(得分:1)

import re
s = 'foo bar- blah/hm.lala'
print(re.findall(r"\w+",s))

输出:['foo','bar','blah','hm','lala']

答案 5 :(得分:0)

这有效:

import re

test_str = '    #   include "header.hpp"'

match = re.match(r'\s*#\s*include\s*("[\w.]*")', test_str)
if match:
    print match.group(1)

答案 6 :(得分:0)

虽然不准确,但大多数解析头指令都是这样的

(?m)^\h*#\h*include\h*["<](\w[\w.]*)\h*[">]

其中,(?m)是多行模式,\ h是水平空格(又名[^ \ S \ r \ n])。

答案 7 :(得分:-1)

导入 re.split('[^ a-zA-Z0-9]',string_to_split)

所有!(字母数字)字符