Reputation: 6227
I am trying to build a function which verifies that a string does not contain curly brackets ({
and }
), other than those which may be used for one-level formatting. That is, I wish to allow curly brackets which may vanish after a single call to the .format
method of the string.
For example, if this verification function is called no_curly_braces
, the following results should be returned:
>>> no_curly_brackets("word")
True
>>> no_curly_brackets("{word") # False, as .format raises ValueError
False
>>> no_curly_brackets("{}word") # True, as .format(3) returns '3word'
True
>>> no_curly_brackets("{word}") # True, as .format(word=3) returns '3'
True
>>> no_curly_brackets("{{word}}") # False, as .format returns '{word}'
False
>>> no_curly_brackets("{{{word}}}") # False, as .format(word='a') returns '{a}'
False
>>> no_curly_brackets("{word}{{}}") # False, as .format(word=3) returns '3{}'
False
and so on.
My problem is that attempts like "{" in str
will fail (as templates may hold these curly brackets), and I cannot wish to format without knowing what I should provide to the .format
method, in order to try to make the relevant curly brackets vanish.
Upvotes: 2
Views: 174
Reputation: 1123620
Use the string.Formatter()
class:
from string import Formatter
def no_curly_brackets(fmt):
try:
parsed = Formatter().parse(fmt)
return not any('{' in lt or '}' in lt for lt, _, _, _ in parsed)
except ValueError:
return False
Basically anything that's parsable as a format and doesn't contain a curly brace in the parsed literal text would be True
.
This matches all your test cases:
>>> for test in tests:
... print test, no_curly_brackets(test)
...
word True
{word False
{}word True
{word} True
{{word}} False
{{{word}}} False
{word}{{}} False
plus a few of my own:
>>> no_curly_brackets('word}}')
False
>>> no_curly_brackets('{{word')
False
>>> no_curly_brackets('word{{}}')
False
Upvotes: 6
Reputation: 62459
Here's an answer based on my comment above:
def no_curly_brackets(fmt):
n = 0
for c in fmt:
if c == '{':
n=n+1
elif c == '}':
n=n-1
if n < 0 or n > 1:
return False
return (n == 0)
Some sample results:
word True
{word False
{}word True
{word} True
{{word}} False
{{{word}}} False
{word}{{}} False
Upvotes: 2