Ich versuche, gültige Java-Anmerkungen in einem Text zu erkennen. Hier ist mein Testprogramm (ich bin derzeit alle Leerzeichen der Einfachheit halber ignorieren, werde ich diese später hinzufügen):Python Regex für Java-Annotationen
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
Also im Grunde, was ich habe scheint für Null oder Eins Parameter zu arbeiten. Jetzt versuche ich, die Syntax auf Null oder mehr Parameter zu erweitern, wie im letzten Beispiel.
ich kopiert dann die Regex Teil, der die Zuordnung und prepend es durch ein Komma für die zweite bis n-te Gruppe darstellt: aber
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))*\))?$'
Das kann nicht Arbeit (diese Gruppe jetzt mit * statt?) . Das Problem scheint zu sein, wie man mit dem ersten Element umgeht, denn das muss optional sein, dann werden Strings wie das erste Extension-Beispiel '@SomeName2(,value="ord_nbr ASC, name")'
akzeptiert, was falsch ist. Ich habe keine Ahnung, wie man die zweite bis n-te Zuweisung nur vom Vorhandensein des ersten (optionalen) Elements abhängig macht.
Kann es getan werden? Ist es so gemacht? Wie löst man das am besten?
Dank
(Regex-Teil, der die Zuordnung darstellt) + Funktioniert das oben für Sie, "+" zeigt eins oder übereinstimmt. Machen Sie die 2. bis N-ten optional und abhängig von ersten. – subiet
Hinweis: Machen Sie es sich nicht zur Gewohnheit, 're.IGNORECASE' zu verwenden. Es ist langsamer (nicht so eine große Sache) und ist schrecklich, wenn es mit Unicode verwendet wird (eine große Sache.) –
Versuchen Sie, eine gültige Java-Annotation oder eine eingeschränkte Teilmenge zu erkennen? Ich kann mir mehrere perfekt gültige Java-Anmerkungen vorstellen, die von Ihrer Regex nicht behandelt werden. –