我正在处理以下数据...
*
标记属性 A
**
标记属性 B
***
标记属性 A 和 B
text1 = "spam*eggs" # A
text2 = "eggs**spam" # B
text3 = "spam***spam" # A & B
测试属性 B 很容易,
"**" in <string>
但是使用相同的策略测试属性 A 会给出 text2 的误报。
>>> "*" in text2
True
我想测试属性 A。有没有一种pythonic方法可以在不使用正则表达式的情况下做到这一点?我不想使用正则表达式,因为我与不熟悉它的初学者共享代码。
试试这个:
idx = txt.index('*')
if txt[idx+1] != '*':
print 'A'
elif txt[idx+2] != '*':
print 'B'
else:
print 'A & B'
上述情况将引发极端情况的异常 - 例如,如果字符串不存在,或者字符串是最后一个字符。此解决方案具有执行文本的单次遍历(调用index()
)的额外好处。
如果没有正则表达式,你可以做这样的事情:
if "***" in mystr:
print "Property A & B"
elif "**" in mystr:
print "Property B"
elif "*" in mystr:
print "Property A"
您可以计算"*"的出现次数:
>>> text1.count('*')
1
>>> text2.count('*')
2
>>> text3.count('*')
3
所以你的支票会text.count('*') in (1, 3)
也就是说,我同意评论者的观点 - 正则表达式适用于此类问题。
>>> properties = {1: 'A', 2: 'B', 3: 'A & B'}
>>> import re
>>> text = 'eggs***spam'
>>> match = re.search(r'*+', text)
>>> if match:
... print properties[len(match.group(0))]
... else:
... print 'None'
A & B
,我不会说它是Pythonic,但你可以对它们进行分组,并确保连续出现的长度是一定的长度 - 1或3以排除**
例如,例如:
from itertools import groupby
print any(k=='*' and len(list(g)) in (1, 3) for k, g in groupby(s))
目前尚不清楚您是只想测试属性 A(如文本中所示)还是 A 或 C(如标题中所示)。(C 是 A 和 B)
要只获得 1 或 3 而不是 2 的 True
或False
,您可以使用逻辑的代码改写:
result = '***' in x or (not '**' in x and '*' in x)
要根据模式取出ABC
字母,请执行以下操作:
result = ['None','A','B','C'][('*' in x) + ('**' in x) + ('***' in x)]
只测试属性 A(一星),而不会在两颗或三颗星上失败。(编辑:简化。如果**
不存在,则***
也不存在):
isItA = '*' in x and not '**' in x