1# coding: utf-8
2"""Utilities for working with strings and text."""
3
4
5def tonumber(s):
6    """
7    Convert string to number, raise ValueError if s cannot be converted.
8    """
9    # Duck test.
10    try:
11        stnum = s.upper().replace("D", "E")  # D-01 is not recognized by python: Replace it with E.
12        # stnum = strip_punct(stnum)         # Remove punctuation chars.
13        return float(stnum)                  # Try to convert.
14
15    except ValueError:
16        raise
17
18    except Exception:
19        raise RuntimeError("Don't know how to handle type %s: %s" % (type(s), str(s)))
20
21
22def nums_and_text(line):
23    """
24    Split line into (numbers, text).
25    """
26    tokens = line.split()
27    text = ""
28    numbers = []
29
30    for tok in tokens:
31        try:
32            numbers.append(tonumber(tok))
33        except ValueError:
34            text += " " + tok
35
36    return numbers, text
37
38
39def rreplace(s, old, new, occurrence):
40    """
41    replace old with new in string but, instead of starting from the beginning
42    as replace does, starting from the end.
43
44    >>> s = '1232425'
45    >>> assert rreplace(s, '2', ' ', 2) == '123 4 5'
46    >>> assert rreplace(s, '2', ' ', 3) == '1 3 4 5'
47    >>> assert rreplace(s, '2', ' ', 4) == '1 3 4 5'
48    >>> assert rreplace(s, '2', ' ', 0) == '1232425'
49    """
50    # Based on:
51    # https://stackoverflow.com/questions/2556108/rreplace-how-to-replace-the-last-occurrence-of-an-expression-in-a-string
52    li = s.rsplit(old, occurrence)
53    return new.join(li)
54