Question

I'm receiving my data in a string through a serial port communication. That part is working fine. The data is in the following format:

Distance run: 36in.
Direction in degrees: 275

Total of person founds:11
New Person found in:
Lat/Long: 18.38891, -66.12174
Date: 5/4/2013  Time: 19:13:35.0

Total of person founds:12
New Person found in:
Lat/Long: 18.38891, -66.12175
Date: 5/4/2013  Time: 19:13:37.0


Distance run: 15in.
Direction in degrees: 215

Total of person founds:13
New Person found in:
Lat/Long: 18.38891, -66.12174
Date: 5/4/2013  Time: 19:13:39.0


Distance run: 30in.
Direction in degrees: 180

But this can vary a little cause in between of each blog of persons founds (which includes it position in lat/long, date and time) there can be another distance run and direction in degrees.

I've tried Regex but not sure on how to use it well. I even have a regular expression that extract only the numbers.

var xnumbers = Regex.Split(strFileName, @"[^0-9\.\-]+").Where(c => c != "." && c.Trim() != "");

What I want is to extract the specific value of let say distance run: which the first value is 36in and store it and so on. Then get the value of the direction in degrees and store it in another variable and finally get the lat & long and store it in other variable. I need this values to create a List to later use that data and plot it. I already have the drawing part.

I tried this:

I know this patter takes only in consideration that distance is 2 numbers only but that value can be 1 or 3 numbers (example: Distance Run: 1in or Distance run: 219 in)

string pattern = @"^Distance Run:(?<distance>.{2}),Direction in degrees:,(?<degress>. {3}),Lat/Long:(\+|\-)(?<latlong>.{18})$";

string distance = string.Empty;
string degrees = string.Empty;
string latlong = string.Empty;


Regex regex = new Regex(pattern);

if (regex.IsMatch(strFileName)) // strFileName is the string with the data
{
    Match match = regex.Match(strFileName);
    foreach (Capture capture in match.Groups["distance"].Captures)
        distance = capture.Value;
    foreach (Capture capture in match.Groups["degree"].Captures)
        degrees = capture.Value;
    foreach (Capture capture in match.Groups["Lat/Long"].Captures)
        latlong = capture.Value;
}

But is not working. I would thank for any help and advice. Thanks in advance.

Was it helpful?

Solution

You can just define a variable repetition by passing 2 values within {}, e.g. \d{1,3} would match 1-3 digits.

But overall, I'd probably use less regular expressions for this, given the format is rather nice to parse:

  • First of all I'd loop through all lines as an array of strings.
  • If one line is empty, ignore it, if two consecutive lines are empty, a new dataset is created.
  • If the line includes a : you split the line there: the left part becomes the key, the right part the value.
  • If the line doesn't include a : it's either ignored or an error flag raised (or exception thrown or whatever).
  • You can then use a simple string match (faster than a regular expression) to determine the meaning of the "key".
  • Another regular expression (or just something like Double.Parse()) then extracts the value from the right. Keep in mind that these conversion functions will simply skip invalid characters and drop anything trailing them.
  • The more complex entries (like coordinates or time stamp; or the entries where the unit is important) can then be parsed using a simple regular expression.

Simplified code (not necessarily 100% compileable/correct):

String[] lines = fileContents.Split({'\n'}); // split the content into separate lines

bool wasEmpty = false;
foreach (String line in lines) {
    line = line.Trim(); // remove leading/trailing whitespaces
    if (line.Length == 0) { // line is empty
        if (wasEmpty) { // last line was empty, too
            // init a new dataset
        }
        else
            wasEmpty = true;
        continue; // skip to next entry
    }
    wasEmpty = false;
    String content = line.split({':'}); // split the line into a key/value pair
    if (content.Length != 2) // not exactly two entries
        continue; // skip
    // content[0] now has the "key" (like "Lat/Long")
    // content[1] now has the "value" (like "18.38891, -66.12175")
    // both can be evaluated using regular expressions
}

OTHER TIPS

In your regular expression, the name of the second part is degress. In code, you're using degree instead.

In your regular expression, the name of the second part is latlong. In code, you're using Lat/Long instead.

So no, as is, you won't be able to get those two groups.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top