tags:

views:

136

answers:

4

Hallo,

I have the following syntax:

@AAAA{tralala10aa,
  author = {Some Author},
  title = {Some Title},
  booktitle = {Some Booktitle},
  year = {2010},
  month = {March},
  booktitle_short = {CC 2010},
  conference_url = {http://www.mmmm.com},
  projects = {projects}
}

....

I've made the following regular expression:

@[A-Z]*[{][a-z0-9]*[,]

but I need the whole text block. How can I do it ?

+4  A: 

It seems like you would be much better off using a context-free grammar instead of a regular expression in this case. Consider using a parser generator, such as CUP or ANTLR.

Jay Conrod
Woudn't be easy to match all with @AAA{ some text }} ?I don't know how to express: "some text"and at the end }}
aphex
I think Anon's regular expression will get the text, but ONLY if nested braces are one-deep. A CFG will also make it easy to parse the individual statements inside the block.
Jay Conrod
If you want to match more than one level of nesting, you have three options: Extend the regular expression to those deeper levels (assuming a finite depth), use a recursive (and thus nonregular) expression (Perl has these, don't know about Java), or use a proper parser.
Anon.
Grats on all the upvotes, but it seems I found a simple regexp that satisfies the requirements ;)
Carl Smotricz
+2  A: 

If the nesting on braces is only allowed one-deep:

/@[A-Z]*{([^{}]*+|{[^{}]*+})*}/

Note the use of the possessive quantifier *+ - without it, this can take quite a long time on failed matches.

I'm not sure if Java supports it - if it doesn't, remove it, but keep in mind the poor failure-behaviour.

Anon.
Is there anything in this expression or answer text making this expression multiline capable?
Carl Smotricz
You don't need the leading and trailing slashes, the Regex constructor in Java just takes a regular String (so there are instances where you'll have to do double escaping but not in this case). Also, it does support possessive quantifiers so you won't have a problem there.
CurtainDog
Would `[^{}]` in a Java regex match newlines by default? If not, the singleline attribute `/s` would need to be specified.
Anon.
@Anon: I don't think so. That's why I asked.
Carl Smotricz
A: 

I would not use regex, I would tokenize the string and build up a dictionary. Sorry, this is a Python implementation (not Java):

>>> s ="""@AAAA{tralala10aa,
  author = {Some Author},
  title = {Some Title},
  booktitle = {Some Booktitle},
  year = {2010},
  month = {March},
  booktitle_short = {CC 2010},
  conference_url = {http://www.mmmm.com},
  projects = {projects}
}"""
>>> 
>>> s
'@AAAA{tralala10aa,\n  author = {Some Author},\n  title = {Some Title},\n  booktitle = {Some Booktitle},\n  year = {2010},\n  month = {March},\n  booktitle_short = {CC 2010},\n  conference_url = {http://www.mmmm.com},\n  projects = {projects}\n}'
>>> 
>>> 
>>> lst = s.replace('@AAA', '').replace('{', '').replace('}', '').split(',\n')
>>> lst
['Atralala10aa', '  author = Some Author', '  title = Some Title', '  booktitle = Some Booktitle', '  year = 2010', '  month = March', '  booktitle_short = CC 2010', '  conference_url = http://www.mmmm.com', '  projects = projects\n']
>>> dct = dict((x[0].strip(), x[1].strip()) for x in (y.split('=') for y in lst[1:]))
>>> dct
{'booktitle_short': 'CC 2010', 'title': 'Some Title', 'booktitle': 'Some Booktitle', 'author': 'Some Author', 'month': 'March', 'conference_url': 'http://www.mmmm.com', 'year': '2010', 'projects': 'projects'}
>>> 
>>> dct['title']
'Some Title'
>>> 

Hopefully the code above seems self explanatory.

Hamish Grubijan
-1 - this doesn't answer this (clearly) Java-specific question.
Stephen C
Nevertheless, it is a better solution than using a regexp.
quant_dev
@quant_dev - if you think dictionaries are a better way to solve the problem, code the solution in Java and post it as your own answer.
Stephen C
+2  A: 

If the "block" always ends with a lone closing brace, then this maywill do it:

"(?ms)@[A-Z]+\\{.+?^\\}$"

Where (?ms) sets the expression to "multiline" and "dotall" (so the .+ can also match newlines), and the stuff at the end matches a closing brace on a line by itself.

The question mark in the middle makes the .+ match non-greedy so it won't match all blocks up to and including the last block in the file.

Carl Smotricz
It doesn't work. When i have more blocks it matches them all as one.
aphex
Oops, sorry! I just corrected a bug in my expression. Please try again!
Carl Smotricz
It works perfect :) Thanks very much !
aphex
Excellent! Thank you for the feedback, I'd been chewing my nails here.
Carl Smotricz