When the rules for what is OK become hard to define, you might consider this binary search approach that tries to find the bound.
def binsearch_prefix(seq, predicate):
best_upper = 0
lower, upper = 0, len(seq)
while lower < upper:
mid = (lower + upper) / 2
if predicate(seq[:mid]):
best_upper = mid
lower = mid + 1
else:
upper = mid
return seq[:best_upper]
It will return the part of the string that you consider acceptable. For example, this could be your accept function:
def can_float(s):
try:
float(s)
return True
except ValueError:
return False
Example:
print binsearch_prefix(can_float, "1234alpha") # "1234"
print binsearch_prefix(can_float, "a1234asdf") # ""
print binsearch_prefix(can_float, "1234.56yt") # "1234.56"
You may then format the prefix any way you like.