2017-07-17 69 views
4

如何轻松检查字符串是否以4*N空格开头,其中N是一个正整数?如何轻松检查一个字符串是否以4N空格开头?

我当前的代码是:

def StartsWith4Nspaces(string): 
    count = 0 
    for c in string: 
     if c == ' ': 
      count += 1 
     else: 
      break 
    return count > 0 and count % 4 == 0 

有没有写下来一个更Python的方式?

我有点希望得到一个单一的声明(虽然比上述任何更干净的将是伟大的)。

谢谢。

+1

以'4 * N + 1'开头的字符串是否符合您以'4 * N'开头的要求?就像你在字符串开头的空格的数量是* * * * * * * * * * * * *一样,或者只是以'4 * N'空格开始的字符串。 –

回答

4

您可以只检查它像这样:

my_string[:4*N] == ' ' * 4*N 

您还可以将你的这张支票到lambda

check = lambda my_string, N: my_string[:4*N] == ' ' * 4*N 

,并称呼其为:

check(' asdas', 2) # -> True 
check(' asdas', 3) # -> False 

或者,如果您想为任何原因对N进行硬编码(N = 3):

check = lambda my_string: my_string[:12] == ' ' * 12 

编辑:如果第4n个+ 1个字符需要是一个空间,你可以结合到你的lambda

check_strict = lambda my_string, N: my_string[:4*N] == ' ' * 4*N and my_string[4*N + 1] != ' ' 

check_strict = lambda my_string: my_string[:12] == ' ' * 12 and my_string[13] != ' ' 
+0

需要一个参数'N'。 OP似乎想要这样做没有这个参数 – inspectorG4dget

+0

是否有一个特定的原因,你选择索引切片,而不是'str.startswith()'?这看起来像'startswith()'的确切用例是专为...... –

+0

也是这个答案是错误的 - 在OP的问题中的代码要求“计数%4 == 0”,即*正好*'4 * N'空格是必需的,没有更多。 –

1
def startsWith4Nspaces(s): 
    if not s: return False 

    numLeadingSpaces = len(s) - len(s.lstrip(' ')) 
    if not numLeadingSpaces: return False 
    if numLeadingSpaces%4: return False 
    return True 
2

可以使用lstrip方法剥离开始空白,然后比较剥离和原始字符串的长度:

s = string.lstrip() 
return ((len(string) - len(s)) % 4 == 0 and (len(string) - len(s) != 0) 

(你甚至可以通过不设置变量一行使它秒。)

+0

酷!谢谢! – goodvibration

+2

虽然lstrip可能更好,但是... – goodvibration

+0

@goodvibration谢谢,修正了 –

0

假设你只想要正好 N个空格 - 不多不少于 - 在字符串的开头,然后使用正则表达式;

import re  
def starts_with_four_n_spaces(eval_string): 
    return re.search(r'^(?:\s{4})+(?!\s).*$', eval_string) is not None 

输出;

>>> starts_with_four_n_spaces(' foo') 
False 
>>> starts_with_four_n_spaces('  foo') 
True 

图案^(?:\s{4})+(?!\s).*$工作如下

  • ^(?:\s{4})+匹配的四个空间的倍数;
  • (?!\s)断言这不是跟着另一个空间;
  • .*$匹配任何东西直到字符串结束。
1

有很多选择。请注意,您可以“切分”一个字符串以获取前四个字符。然后你可以将它与空格进行比较。这里有一个例子:

mystring[:4] == ' ' 

您也可以使用字符串的startswith功能:

mystring.startswith(' ') 

注意,如果字符串有5个或多个空格开始,这两种方法仍然会返回True。如果您需要找到起始空格的方法,则正则表达式可能更适合。

如果空格的个数可以是一个变量,只需使用' '*N其中N是要匹配的空格数。

+0

我很确定startswith()比其他解决方案(尤其是使用reg ex)的性能更好。 –

+0

任何收益与正则表达式都将通过迭代找到N并确保没有任何收益而被咀嚼。开始时有6个空格。 –

+0

好点。我会注意到这些方法并不考虑当超过4个空格时会发生什么情况。 – SNygard

1

你可以做到这一点通过以下方式

def StartsWith4Nspaces(s): 
    diff = len(s) - len(s.lstrip(' ')) 
    return ((diff > 0) and not (diff%4)) 

print(StartsWith4Nspaces('abc')) 
print(StartsWith4Nspaces(' ' * 1 + 'abc')) 
print(StartsWith4Nspaces(' ' * 4 + 'abc')) 
print(StartsWith4Nspaces(' ' * 6 + 'abc')) 
print(StartsWith4Nspaces(' ' * 8 + 'abc')) 

输出

False 
False 
True 
False 
True 

基本上你删除前导空格和长度比较差的剥离和原始字符串。

2

使用正则表达式工作体面此:

>>> re.match('(?: {4})*(?!)', '') 
<_sre.SRE_Match object at 0x7fef988e4780> 
>>> re.match('(?: {4})*(?!)', ' ') 
>>> re.match('(?: {4})*(?!)', ' ') 
<_sre.SRE_Match object at 0x7fef988e4718> 
>>> re.match('(?: {4})*(?!)', 'foo') 
<_sre.SRE_Match object at 0x7fef988e4780> 
>>> re.match('(?: {4})*(?!)', ' foo') 
>>> re.match('(?: {4})*(?!)', ' foo') 
<_sre.SRE_Match object at 0x7fef988e4718> 
>>> re.match('(?: {4})*(?!)', '  foo') 
>>> re.match('(?: {4})*(?!)', '  foo') 
<_sre.SRE_Match object at 0x7fef988e4780> 

注意,这会使N为0,并与只包含空格的字符串工作。一个有效的匹配被认为是真实的,但是如果你想要它是一个严格的bool,你可以将结果传递给bool()。用+更换*将迫使N到大于0

0

另一个正则表达式的答案:

re.search('[^ ]', string).start() % 4 == 0

查找第一个非空格字符和modulos w.r.t.的索引4。

或者与列表理解相同的方法:

next(i for i, c in enumerate(string) if c != ' ') % 4 == 0

0

可以slice字符串,并使用all()内置的方法来检查切片string是你所需要的,如下:

st = ' testString' 
N = 1 
print all(x == ' ' for x in st[:4*N]) 

将输出

True 
相关问题