使用Python抓取一行是空格/缩进

时间:2010-02-15 19:55:59

标签: python whitespace indentation

基本上,如果我有一行以缩进开头的文本,那么获取该缩进并将其放入Python中的变量的最佳方法是什么?例如,如果该行是:

\t\tthis line has two tabs of indention

然后它将返回'\ t \ t'。或者,如果该行是:

    this line has four spaces of indention

然后它将返回四个空格。

所以我想你可以说我只需要从第一个非空白字符到结尾的字符串中删除所有内容。想法?

6 个答案:

答案 0 :(得分:24)

import re
s = "\t\tthis line has two tabs of indention"
re.match(r"\s*", s).group()
// "\t\t"
s = "    this line has four spaces of indention"
re.match(r"\s*", s).group()
// "    "

要剥离前导空格,请使用lstrip


由于可能会质疑正则表达式的效率,我已经做了一些分析来检查每个案例的效率。

非常长的字符串,非常短的前导空间

RegEx> Itertools>> lstrip

>>> timeit.timeit('r.match(s).group()', 'import re;r=re.compile(r"\s*")s="          hello world!"*10000', number=100000)
0.10037684440612793
>>> timeit.timeit('"".join(itertools.takewhile(lambda x:x.isspace(),s))', 'import itertools;s="          hello world!"*10000', number=100000)
0.7092740535736084
>>> timeit.timeit('"".join(itertools.takewhile(str.isspace,s))', 'import itertools;s="          hello world!"*10000', number=100000)
0.51730513572692871
>>> timeit.timeit('s[:-len(s.lstrip())]', 's="          hello world!"*10000', number=100000)
2.6478431224822998

非常短的字符串,非常短的前导空间

lstrip> RegEx> Itertools

如果你可以将字符串的长度限制为chars或更少的字符,那么lstrip技巧可能更好。

>>> timeit.timeit('r.match(s).group()', 'import re;r=re.compile(r"\s*");s="          hello world!"*100', number=100000)
0.099548101425170898
>>> timeit.timeit('"".join(itertools.takewhile(str.isspace,s))', 'import itertools;s="          hello world!"*100', number=100000)
0.53602385520935059
>>> timeit.timeit('s[:-len(s.lstrip())]', 's="          hello world!"*100', number=100000)
0.064291000366210938

这表明lstrip技巧大致为O(√n),如果前导空格的数量不多,则RegEx和itertool方法为O(1)。

非常短的字符串,非常长的前导空间

lstrip>> RegEx>>> Itertools

如果有很多前导空格,请不要使用RegEx。

>>> timeit.timeit('s[:-len(s.lstrip())]', 's=" "*2000', number=10000)
0.047424077987670898
>>> timeit.timeit('r.match(s).group()', 'import re;r=re.compile(r"\s*");s=" "*2000', number=10000)
0.2433168888092041
>>> timeit.timeit('"".join(itertools.takewhile(str.isspace,s))', 'import itertools;s=" "*2000', number=10000)
3.9949162006378174

非常长的字符串,非常长的前导空间

lstrip>>> RegEx>>>>>>>> Itertools

>>> timeit.timeit('s[:-len(s.lstrip())]', 's=" "*200000', number=10000)
4.2374031543731689
>>> timeit.timeit('r.match(s).group()', 'import re;r=re.compile(r"\s*");s=" "*200000', number=10000)
23.877214908599854
>>> timeit.timeit('"".join(itertools.takewhile(str.isspace,s))', 'import itertools;s=" "*200000', number=100)*100
415.72158336639404

如果非空间部分不是很多,则显示所有方法大致缩放为O(m)。

答案 1 :(得分:12)

偷偷摸摸的方式:滥用lstrip

fullstr = "\t\tthis line has two tabs of indentation"
startwhites = fullstr[:len(fullstr)-len(fullstr.lstrip())]

通过这种方式,您无需了解空白的所有细节!

(感谢Adam纠正)

答案 2 :(得分:4)

也可以使用str.isspaceitertools.takewhile代替正则表达式。

import itertools

tests=['\t\tthis line has two tabs of indention',
       '    this line has four spaces of indention']

def indention(astr):
    # Using itertools.takewhile is efficient -- the looping stops immediately after the first
    # non-space character.
    return ''.join(itertools.takewhile(str.isspace,astr))

for test_string in tests:
    print(indention(test_string))

答案 3 :(得分:-1)

def whites(a):
return a[0:a.find(a.strip())]

基本上,我的想法是:

  1. 找一条起跑线
  2. 查找起始行和已剥离的
  3. 之间的差异

答案 4 :(得分:-2)

如何使用匹配任何空格字符的regex \s*。您只需要行开头的空格,以便search使用正则表达式^\s*match使用\s*

答案 5 :(得分:-2)

如果您对使用正则表达式感兴趣,可以使用它。 /\s/通常匹配一个空格字符,因此/^\s+/将匹配从一行开始的空格。