Regex for Parsing Simple Text Data File
Can anyone give me a hand with regex application?
I am reading a list of "locations" for a simple text adventure (the ones that are so popular on the same day). However, I'm not sure how to get the input.
All locations follow the following format:
<location_name>, [<item>]
[direction, location_name]
For instance:
Albus Square, Flowers, Traffic Cone
NORTH, Franklandclaw Lecture Theatre
WEST, Library of Enchanted Books
SOUTH, Furnesspuff College
Library of Enchanted Books
EAST, Albus Square
UP, Reading Room
(Subsequent locations are separated by a blank line.)
I store them as Location objects with structure:
public class Location {
private String name;
private Map<Direction, Location> links;
private List<Item> items;
}
I am using a method to extract data from a url and create Location objects from the text read, but I have a complete block to do this. I think a regex will be useful. Can anyone lend me the hand I need?
a source to share
Agree w / willcodejavaforfood, regex can be used, but not much of a push here.
It looks like you just need a little help on the algorithm (sloppy p-code follows) ...
currloc = null
while( line from file )
if line begins w/ whitespace
(dir, loc) = split( line, ", " )
add dir, loc to currloc
else
newlocdata = split( line, ", " )
currloc = newlocdata[0]
for i = 1 to size( newlocdata ) - 1
item = newlocdata[i]
add item to currloc
a source to share
You don't want to use text format for this:
-
What happens when you have more than one floral element? Are they all the same? Can't an adventurer assemble a bouquet by picking individual flowers in multiple locations?
-
There will probably be several rooms with the same name ("basement", "street corner"), that is, filler rooms that add to the atmosphere, but nothing to play with. However, they do not receive a description. How do you separate them?
-
What if the name contains a comma?
-
Eventually you will want to use Unicode for foreign names or formatting instructions.
Since this is structured data that can contain many odd cases, I suggest using XML for this:
<locations>
<location>
<name>Albus Square</name>
<summary>Short description for returning adventurer</summary>
<description>Long text here ... with formatting, etc.</description>
<items>
<item>Flowers</item>
<item>Traffic Cone</item>
<items>
<directions>
<north>Franklandclaw Lecture Theatre</north>
<west>Library of Enchanted Books</west>
<south>Furnesspuff College</south>
</directions>
</location>
<location>
<name>Library of Enchanted Books</name>
<directions>
<east>Albus Square</east>
<up>Reading Room</up>
</directions>
</location>
</locations>
This allows for much more flexibility, solves many problems such as formatting description text, Unicode characters, etc. Also, you can use more than one element / place with the same name by using identifiers (numbers) instead of text.
a source to share
I can't get into Java mode right now, so here's the pseudo code here:
Data = MyString.split('\n\n++\s*+');
for ( i=0 ; i<Data.length ; i++ )
{
CurLocation = Data[i].split('\n\s*+');
LocationInfo = CurLocation[0].split(',\s*+');
LocationName = LocationInfo[0];
for ( n=1 ; n<LocationInfo.length ; n++ )
{
Items[n-1] = LocationInfo[n];
}
for ( n=1 ; n<CurLocation.length ; n++ )
{
DirectionInfo = LocationInfo[n].split(',\s*+');
DirectionName = DirectionInfo[0];
for ( x=1 ; x<DirectionInfo.length ; x++ )
{
DirectionLocation[x-1] = DirectionInfo[x];
}
}
}
a source to share
I think using XML is overkill (sparrow shooting with guns) while regexes are "underkill" (using too weak a tool, cleaning floors with a toothbrush).
The correct balance sounds like ".ini format" or "message headers with sections". For python, there are library docs at http://docs.python.org/library/configparser.html .
A short example:
[albus_square]
name: Albus Square
items: Flowers, Traffic Cone
north: lecture_theatre
west: library_enchanted_books
south: furnesspuff_college
I would guess there is a Java library for this format. As another poster pointed out, you might have a name clash, so I allowed the "name:" field to be added. The name in square brackets will be a unique identifier.
a source to share