Я новичок в Python, и я застрял с проблемой. У меня есть входной файл, который содержит данные, как показано ниже:

12345    67890     afghe
abcde    23456     0abcd
34567    __fred01  45678
123.456  12345a    123.
.456     ab00cd    00ab00

При использовании регулярного выражения необходимо проанализировать каждый литерал и классифицировать, является ли литерал строкой или целым числом или с плавающей запятой. Фрагмент кода выглядит примерно так:

def processtoken(token):
    #Replace the following line with your code to classify
    # the string in 'token' according to your three Regular
    # Expressions and print the appropriate message.
    print('Inside Process Token')

    match = re.search(r'(0|[1-9][0-9]*|0[oO]?[0-7]+|0[xX][0-9a-fA-F]+|0[bB][01]+)[lL]?', token)
    matchfp = re.search(r'^[0-9]+\.?[0-9]+$',token)
    if match:
        print(match.group(),'matches INT')
    elif matchfp:
        print(matchfp.group(),'matches FP')

Моя проблема заключается в том, как мне структурировать код для проверки нескольких условий регулярных выражений для каждого пройденного токена. На данный момент с плавающей запятой, если условие не проверено. Я хочу проверить токен, первое целочисленное регулярное выражение, если он соответствует или если он соответствует регулярному выражению с плавающей запятой или соответствует строке. Любая помощь будет оценена.

3
np05 2 Мар 2018 в 06:18

3 ответа

Лучший ответ

Я бы структурировал проблему следующим образом:

integer_regex = r"^...$"
float_regex = r"^...$"
string_regex = r"^...$"

def processToken(token):

    if re.search(integer_regex, token):
        print(token, 'matches INT')
    elif re.search(float_regex, token):
        print(token, 'matches FLOAT')
    elif re.search(string_regex, token):
        print(token, 'matches STR')
    else:
        print(token, 'unknown')

Заполнение ваших шаблонов в переменных *_regex выше.

Также обратите внимание, что ваш шаблон float не годится, так как он также соответствует int:

r'^[0-9]+\.?[0-9]+$'

Поскольку десятичная точка не является обязательной. Возможно, вам лучше разбить шаблон на три варианта, начиная с «.» И заканчивая «.» или содержит «.» между числами. Кроме того, в вашем целочисленном шаблоне '?' в восьмеричном разделе неверно:

0[oO]?[0-7]+

На данный момент мы пытаемся зафиксировать восьмеричное значение, поэтому префикс не является обязательным:

0[oO][0-7]+

Вы получили это правильно для шестнадцатеричного и двоичного.

1
cdlane 2 Мар 2018 в 04:06

Разделите текст, используйте функцию isdigit() для проверки int, затем try для float и захватите ValueError для string.

for m in string.split():
    if m.isdigit():
        print(m, 'Int')
    else:
        try:
            float(m)
            print(m, 'Float')
        except ValueError:
            print(m, 'STR')

Выход:

('12345', 'Int')('67890', 'Int')('afghe', 'STR')('abcde', 'STR')('23456', 'Int')('0abcd', 'STR')('34567', 'Int')('__fred01', 'STR')('45678', 'Int')('123.456', 'Float')('12345a', 'STR')('123.', 'Float')('.456', 'Float')('ab00cd', 'STR')('00ab00', 'STR')

Код демо

1
Srdjan M. 2 Мар 2018 в 04:51
>>> test = """\
... 12345    67890     afghe
... abcde    23456     0abcd
... 34567    __fred01  45678
... 123.456  12345a    123.
... .456     ab00cd    00ab00"""
>>> def what_is_it(s):
...     print("'{}'".format(s), end=' ')
...     try:
...         as_float = float(s)
...     except ValueError:
...         return 'matches STRING'
...     else:
...         if as_float.is_integer():
...             return 'matches INT'
...         return 'matches FP'
... 
>>> for line in test.splitlines():
...     for token in line.split():
...         print(what_is_it(token))
...     print()
... 
'12345' matches INT
'67890' matches INT
'afghe' matches STRING

'abcde' matches STRING
'23456' matches INT
'0abcd' matches STRING

'34567' matches INT
'__fred01' matches STRING
'45678' matches INT

'123.456' matches FP
'12345a' matches STRING
'123.' matches INT

'.456' matches FP
'ab00cd' matches STRING
'00ab00' matches STRING
0
G_M 2 Мар 2018 в 03:58