lms.util.string

 1import re
 2import typing
 3
 4INT_PATTERN: re.Pattern = re.compile(r'^\d+$')
 5
 6def compare_maybe_ints(a: typing.Union[str, int, None], b: typing.Union[str, int, None]) -> int:
 7    """
 8    Perform a standard comparison (-1, 0, 1) on two strings that are presumed to be integers.
 9    If they are not integers, compare them as strings.
10    """
11
12    if ((a is None) or (b is None)):
13        if ((a is None) and (b is None)):
14            return 0
15
16        if (a is None):
17            return -1
18
19        return 1
20
21    values = [a, b]
22    has_str = False
23
24    for (i, value) in enumerate(values):
25        if (isinstance(value, int)):
26            continue
27
28        value = str(value)
29        if (INT_PATTERN.match(value) is not None):
30            value = int(value)
31        else:
32            has_str = True
33
34        values[i] = value
35
36    if (has_str):
37        values = [str(value) for value in values]
38
39    if (values[0] < values[1]):  # type: ignore[operator]
40        return -1
41
42    if (values[0] > values[1]):  # type: ignore[operator]
43        return 1
44
45    return 0
INT_PATTERN: re.Pattern = re.compile('^\\d+$')
def compare_maybe_ints(a: Union[str, int, NoneType], b: Union[str, int, NoneType]) -> int:
 7def compare_maybe_ints(a: typing.Union[str, int, None], b: typing.Union[str, int, None]) -> int:
 8    """
 9    Perform a standard comparison (-1, 0, 1) on two strings that are presumed to be integers.
10    If they are not integers, compare them as strings.
11    """
12
13    if ((a is None) or (b is None)):
14        if ((a is None) and (b is None)):
15            return 0
16
17        if (a is None):
18            return -1
19
20        return 1
21
22    values = [a, b]
23    has_str = False
24
25    for (i, value) in enumerate(values):
26        if (isinstance(value, int)):
27            continue
28
29        value = str(value)
30        if (INT_PATTERN.match(value) is not None):
31            value = int(value)
32        else:
33            has_str = True
34
35        values[i] = value
36
37    if (has_str):
38        values = [str(value) for value in values]
39
40    if (values[0] < values[1]):  # type: ignore[operator]
41        return -1
42
43    if (values[0] > values[1]):  # type: ignore[operator]
44        return 1
45
46    return 0

Perform a standard comparison (-1, 0, 1) on two strings that are presumed to be integers. If they are not integers, compare them as strings.