Регулярное выражение Python для аннотаций JavaPython

Программы на Python
Anonymous
Регулярное выражение Python для аннотаций Java

Сообщение Anonymous »

Я пытаюсь обнаружить в тексте допустимые аннотации Java. Вот моя тестовая программа (сейчас для простоты я игнорирую все пробелы, добавлю позже):

Код: Выделить всё

txts = ['@SomeName2',                   # match
'@SomeName2(',                  # no match
'@SomeName2)',                  # no match
'@SomeName2()',                 # match
'@SomeName2()()',               # no match
'@SomeName2(value)',            # no match
'@SomeName2(=)',                # no match
'@SomeName2("")',               # match
'@SomeName2(".")',              # no match
'@SomeName2(",")',              # match
'@SomeName2(value=)',           # no match
'@SomeName2(value=")',          # no match
'@SomeName2(=3)',               # no match
'@SomeName2(="")',              # no match
'@SomeName2(value=3)',          # match
'@SomeName2(value=3L)',         # match
'@SomeName2(value="")',         # match
'@SomeName2(value=true)',       # match
'@SomeName2(value=false)',      # match
'@SomeName2(value=".")',        # no match
'@SomeName2(value=",")',        # match
'@SomeName2(x="o_nbr ASC, a")', # match

# multiple params:
'@SomeName2(,value="ord_nbr ASC, name")',                            # no match
'@SomeName2(value="ord_nbr ASC, name",)',                            # no match
'@SomeName2(value="ord_nbr ASC, name"insertable=false)',             # no match
'@SomeName2(value="ord_nbr ASC, name",insertable=false)',            # match
'@SomeName2(value="ord_nbr ASC, name",insertable=false,length=10L)', # match

'@SomeName2 ( "ord_nbr ASC, name", insertable = false, length = 10L )',       # match
]

#regex = '((?:@[a-z][a-z0-9_]*))(\((((?:[a-z][a-z0-9_]*))(=)(\d+l?|"(?:[a-z0-9_, ]*)"|true|false))?\))?$'
#regex = '((?:@[a-z][a-z0-9_]*))(\((((?:[a-z][a-z0-9_]*))(=)(\d+l?|"(?:[a-z0-9_, ]*)"|true|false))?(,((?:[a-z][a-z0-9_]*))(=)(\d+l?|"(?:[a-z0-9_, ]*)"|true|false))*\))?$'

regex = r"""
(?:@[a-z]\w*)                               # @ + identifier (class name)
(
\(                                        # opening parenthesis
(
(?:[a-z]\w*)                          # identifier (var name)
=                                     # assigment operator
(\d+l?|"(?:[a-z0-9_, ]*)"|true|false) # either a numeric | a quoted string containing only alphanumeric chars, _, space | true | false
)?                                      # optional assignment group
\)                                        # closing parenthesis
)?$                                         # optional parentheses group (zero or one)
"""

rg = re.compile(regex, re.VERBOSE + re.IGNORECASE)

for txt in txts:
m = rg.search(txt)
#m = rg.match(txt)
if m:
print "MATCH:   ",
output = ''
for i in xrange(2):
output = output + '[' + str(m.group(i+1)) + ']'
print output
else:
print "NO MATCH: " + txt
По сути, то, что у меня есть, похоже, работает для нуля или одного параметра. Теперь я пытаюсь расширить синтаксис до нуля или более параметров, как в последнем примере.

Затем я скопировал часть регулярного выражения, которая представляет назначение, и добавил ее в начало запятая для групп со 2-й по n-ю (в этой группе теперь используется * вместо ?):

Код: Выделить всё

regex = '((?:@[a-z][a-z0-9_]*))(\((((?:[a-z][a-z0-9_]*))(=)(\d+l?|"(?:[a-z0-9_, ]*)"|true|false))?(,((?:[a-z][a-z0-9_]*))(=)(\d+l?|"(?:[a-z0-9_, ]*)"|true|false))*\))?$'
Однако это не может работать. Кажется, проблема заключается в том, как обрабатывать первый элемент, поскольку он должен быть необязательным, тогда будут приняты строки, подобные первому примеру расширения '@SomeName2(,value="ord_nbr ASC, name")', что неправильно. Я понятия не имею, как сделать так, чтобы присвоение со второго по n-е зависело только от наличия первого (необязательного) элемента.

Можно ли это сделать? Это сделано именно так? Как лучше всего решить эту проблему?

Спасибо

Подробнее здесь: https://stackoverflow.com/questions/100 ... nnotations

Вернуться в «Python»