<p>你可以使用regex模式</p>
<pre><code>(?:(\d+)Y)?(?:(\d+)M)?
</code></pre>
<p>也就是说</p>
^{pr2}$
<p>当用于</p>
<pre><code>re.match(r'(?:(\d+)Y)?(?:(\d+)M)?', text).groups()
</code></pre>
<p><code>groups()</code>方法返回分组括号内的匹配部分。^如果组不匹配,则返回{<cd2>}。例如</p>
<pre><code>In [220]: re.match(r'(?:(\d+)Y)?(?:(\d+)M)?', '5Y3M').groups()
Out[220]: ('5', '3')
In [221]: re.match(r'(?:(\d+)Y)?(?:(\d+)M)?', '3M').groups()
Out[221]: (None, '3')
</code></pre>
<hr/>
<pre><code>import re
def parse_aYbM(text):
a, b = re.match(r'(?:(\d+)Y)?(?:(\d+)M)?', text).groups()
if a == b == None:
raise ValueError('input does not match aYbM')
a, b = [int(item) if item is not None else 0 for item in (a, b)]
return a + b/12.0
tests = [
('5Y3M', 5.25),
('5Y', 5.0),
('6M', 0.5),
('10Y11M', 10.917),
('3Y14M', 4.167),
]
for test, expected in tests:
result = parse_aYbM(test)
status = 'Failed'
if abs(result - expected) < 0.001:
status = 'Passed'
print('{}: {} > {}'.format(status, test, result))
</code></pre>
<p>收益率</p>
<pre><code>Passed: 5Y3M > 5.25
Passed: 5Y > 5.0
Passed: 6M > 0.5
Passed: 10Y11M > 10.9166666667
Passed: 3Y14M > 4.16666666667
</code></pre>
<hr/>
<p>注意,如果<code>parse_aYbM</code>的输入与模式不匹配,会发生什么情况还不清楚。对于上面的代码,不匹配将引发<code>ValueError</code>:</p>
<pre><code>In [227]: parse_aYbM('foo')
ValueError: input does not match aYbM
</code></pre>
<p>但部分匹配可能返回一个值:</p>
<pre><code>In [229]: parse_aYbM('0Yfoo')
Out[229]: 0.0
</code></pre>