Как проверить, соответствует ли токен шаблону RegEx?

Я пишу лексический анализатор c/c++ на python.

Есть над чем поработать, но пока я застрял. Я хочу проверить имена переменных с помощью шаблона RegEx:

(?:\w+\s+)([a-zA-Z_][a-zA-Z0-9]+)/g

Хотя на регулярное выражение паттерн работает нормально

Пример

Мой код для этого:

РЕЗЮМЕ:

Код для проверки соответствия строки шаблону:

regex = re.compile(r'(?:\w+\s+)([a-zA-Z_][a-zA-Z0-9]+)\b')
if re.search(regex, token) == True: #if token matches the pattern
            print(token + ' : Variable Name')
import re


#dictionaries:
#1 operators
operators = {'=': 'Assignment',
    '+': 'Additon',
    '-' : 'Substraction',
    '/' : 'Division',
    '*': 'Multiplication',
    '++' : 'increment',
    '--' : 'Decrement',
    '<': 'Lower Than',
    '>': 'Greater Than'}
optr_keys = operators.keys()

#2 keywords
keywords = {'int': 'Integer Datatype Indicator',
    'float': 'Floating Point Datatype Indicator',
    'char': 'Character Datatype Indicator',
    'long': 'Long Int Datatype Indicator',
    'double': 'Double Datatype Indicator',
    'short': 'Short Integer Datatype Indicator',
    'unsigned': 'Unsigned Integer Datatype Indicator',
    'void': 'Void Datatype Indicator',
    'struct': 'Structure Datatype Indicator',
    'return': 'Return',
    'if': 'Condition If Keyword',
    'else': 'Condition Else Keyword',
    'while': 'While Loop Indicator',
    'do': 'Do While Loop Indicator',
    'break': 'Break Out Keyword',
    'continue': 'Continue Keyword',
    'switch': 'Switch Keyword',
    'case': 'Case Keyword',
    'sizeof': 'Variable Size Indicator',
    'typedef': 'Function Type Indicator',
    'static': 'Static Type Keyword',
    'goto': 'Go To line Keyword',
    '#include': 'Header Include Indicator'
    }
keyword_keys = keywords.keys()

#3 delimiters
delimiters = {';':'Line Terminator (Semicolon)',
    ' ': 'Single Empty Space'}
delimiter_keys = delimiters.keys()

#4 comment indicators
comments = {r'//' : 'Single Line Comment',
    r'/*' : 'Multiline Comment Start',
    r'*/' : 'Multiline Comment End',
    '/**/' : 'Empty Multiline comment'}
comment_keys = comments.keys()

#5 builtin header files
header_files = {'<stdio.h>': 'Standard Input Output Header',
    '<string.h>':'String Manipulation Library'}
header_keys = header_files.keys()

#6 blocks
blocks = {'{' : 'Blocked Statement Body Open',
    '}':'Blocked Statement Body Closed'}
blocks_keys = blocks.keys()

#7 predefined functions
builtin_functions = {'printf':'Prints To Console',
    'cout': 'Standard Output Function',
    'cin': 'Standard Input Function'}
builtinfunc_keys = builtin_functions.keys()

#8 numbers
numbers = {'0': 'Zero',
    '1': 'One',
    '2': 'Two',
    '3': 'Three',
    '4': 'Four',
    '5': 'Five',
    '6': 'Six',
    '7': 'Se7en',
    '8': 'Eight',
    '9': 'Nine'}
numbers_keys = numbers.keys()

count = 0
cfile = '/some/path/to/sample/file.c'
f = open(cfile, 'r').read()
lines = f.split('\n')
regex = re.compile(r'(?:\w+\s+)([a-zA-Z_][a-zA-Z0-9]+)\b')
for line in lines:
    count = count + 1
    print('\n\n###Line Number', str(count) + '\n')
    tokens = line.split(' ')
    print('Tokens Are ', tokens)

    for token in tokens:
        if '\n' in token:
            position = token.find('\n')
            token=token[:position]

        if token in optr_keys:
            print(token, ' : Operator => ', operators[token])

        elif token in keyword_keys:
            print(token, ' : Keyword => ', keywords[token])

        elif token in comment_keys:
            print(token + ' : Comment => ', comments[token])

        elif '.h' in token:
            print(token + ' : Header File => ', header_files[token])

        elif token in blocks_keys:
            print(token + ' : Block Indicator => ', blocks[token])

        elif token in builtinfunc_keys:
            print(token + ' : Built-in Function => ', builtin_functions[token])

        elif token in numbers:
            print(token + ' : Numbers => ', numbers_keys[token])
        
        else:
            if bool(re.search(regex, token)) == True: #if token matches the pattern
                print(token + ' : Variable Name')

образец вывода:

###Line Number 1

Tokens Are  ['#include', '<stdio.h>', '//', 'This', 'is', 'a', 'header', 'file']
#include  : Keyword =>  Header Include Indicator <stdio.h> : Header File =>  Standard Input Output Header // : Comment =>  Single Line Comment


###Line Number 2

Tokens Are  ['int', 'main()'] int  : Keyword =>  Integer Datatype Indicator


###Line Number 3

Tokens Are  ['{'] { : Block Indicator =>  Blocked Statement Body Open


###Line Number 4

Tokens Are  ['', '', '', '', 'int', 'a;'] int  : Keyword =>  Integer Datatype Indicator


###Line Number 5

Tokens Are  ['', '', '', '', 'a', '=', '10;']
=  : Operator =>  Assignment


###Line Number 6

Tokens Are  ['', '', '', '', 'printf("The', 'value', 'of', 'a', 'is', '%d', '",a);']


###Line Number 7

Tokens Are  ['', '', '', '', 'return', '0;'] return  : Keyword =>  Return


###Line Number 8

Tokens Are  ['}'] } : Block Indicator =>  Blocked Statement Body Closed


###Line Number 9

Tokens Are  ['']

Я ожидаю, что код будет включать имена переменных в вывод, но он просто игнорирует их, поскольку процесс сопоставления не выполняется. Я предполагаю, что что-то не так в том, как я пытаюсь сопоставить токены/строки.

Ваше регулярное выражение [a-zA-Z_][a-zA-Z0-9]+, кажется, запрещает символы подчеркивания, кроме первого символа имени. У вас также может быть однобуквенное имя переменной, поэтому вместо «+» должно быть «', чтобы указать ноль или более вхождений. Я бы предложил [a-zA-Z_][a-zA-Z0-9_]».

Jon Guiton 10.05.2019 21:49

Также будет ли re.search() когда-нибудь ==True? search() возвращает объект соответствия.

Mark 10.05.2019 21:52

@ 9769953 верно. удален re.IGNORECASE

Nitwit 10.05.2019 21:56

@MarkMeyer отредактировал. bool(re.search()) приводит к тому же результату.

Nitwit 10.05.2019 22:01

Вы можете просто использовать if re.search():

Mark 10.05.2019 22:02

@MarkMeyer так и есть. но все еще говорит Нет. не может соответствовать

Nitwit 10.05.2019 22:06

@ 9769953 пробовал нет, я не могу использовать if-elif-elif-else, потому что в этом случае все пробелы и разделители считаются именами переменных. это работает, если я не использую дополнительный if в последнем else, что совпадает с elif.

Nitwit 10.05.2019 22:08

@ 9769953 на основе документов они эквивалентны. docs.python.org/2/library/re.html#module-contents

Nitwit 10.05.2019 22:11

@JonGuiton, спасибо, Джон. это решило это. Я собираюсь переписать это как ответ.

Nitwit 10.05.2019 22:13
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
9
1 345
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема была с самим моим регулярным выражением.

Работает следующий шаблон:

[a-zA-Z_][a-zA-Z0-9_]

Кредиты: Джон Гитон

Другие вопросы по теме