B4A Library [B4X] RegexBuilder - Builder for Regular Expressions

Discussion in 'Additional libraries, classes and official updates' started by Erel, Sep 3, 2017.

  1. Erel

    Erel Administrator Staff Member Licensed User

    This class is compatible with B4A, B4i and B4J.

    Regex is a very powerful tool for parsing strings. However the regex syntax can be a bit difficult if you are not using regex regularly.
    Reading a regex pattern and understanding it is even more challenging.

    The purpose of RegexBuilder is to help with building regex patterns. The API is based on a builder pattern.
    It is more verbose and hopefully more clear.
    It is inspired by VerbalExpressions open source project, though there are many differences between the two.

    Lets start with an example. We want to extract the keys and values from a string that looks like:
    Code:
    Dim s As String = $"R=Red
    G=Green
    B=Blue"$

    Dim rx As RegexBuilder
    rx.Initialize.AppendStartString.StartCapture.Append(rx.CharWord).AppendAtLeastOne.EndCapture 
    'key
    rx.AppendEscaped("="'we don't really need to escape this symbol. No harm is done by escaping it.
    rx.StartCapture.Append(rx.CharAny).AppendZeroOrMore.EndCapture.AppendEndString 'value
    Dim m As Matcher = Regex.Matcher2(rx.Pattern, Regex.MULTILINE, s) 'MULTILINE = StartString and EndString match the beginning and end of each line.
    Do While m.Find
       
    Log("Key: " & m.Group(1))
       
    Log("Value: " & m.Group(2))
    Loop
    Second example, validating a hex number:
    Code:
    Dim rx As RegexBuilder
    rx.Initialize.Append(
    "0x").AppendAnyOf(Array(rx.CharDigit, "abcdefABCDEF")).AppendAtLeastOne
    Log(Regex.IsMatch(rx.Pattern, "0xABcdef123")) 'True
    Log(Regex.IsMatch(rx.Pattern, "312123")) 'False
    Log(Regex.IsMatch(rx.Pattern, "0xHJK")) 'False
    There are several groups of methods in RegexBuilder:

    - Initialize / Clear - Clear the current pattern.
    - Append / AppendEscaped - Add a non-capturing group with the given value. The value will be matched.
    - AppendAnyOf - A single character out of the list of characters (or character classes) will be matched.
    Note that all items in the list are concatenated together.
    - AppendAnyBut - Matches any character not in the list of characters.
    - AppendAtMostOne / AtLeastOne / ZeroOrMore / Count - Sets the number of expected matches of the last group.
    - AppendStartString / EndString - Match the start or end of the string. Use Regex.MULTILINE option to match the start or end of each line.
    - StartCapture / EndCapture - Start or end a capturing group. These groups can be later retrieved with Match.Group.
    - StartNonCapture / EndNonCapture - Start or end a non-capturing group.
    - AppendOr - Adds the or (|) operator.
    - Char properties - Common regex characters sets.
    - Pattern - Returns the pattern.
    - Escape - Escapes the given value and removes any special behavior. It is used by AppendEscaped.
    Code:
    Dim s As String = $",./;'\=""d23df""$
    Log(Regex.IsMatch(rx.Clear.AppendEscaped(s).Pattern, s)) 'true
     

    Attached Files:

  2. imbault

    imbault Well-Known Member Licensed User

    Very nice piece of code,

    Thank you Maestro Erel
     
  3. MarcoRome

    MarcoRome Expert Licensed User

    Yes. Agree ( very nice ) .

    I have this text:

    and i want only this text:

    What i use this new class ?
    Is it possible a little example ?
    Thanks
     
  4. Erel

    Erel Administrator Staff Member Licensed User

    Code:
    Dim test As String
    test = 
    $" map = new GMap2(document.getElementById("map"));
    map.removeMapType(G_HYBRID_MAP);
    map.addMapType(G_PHYSICAL_MAP);
    map.setCenter(new GLatLng(40.82,14.44),12);
    map.addControl(new GSmallMapControl());
    map.addControl(new GMapTypeControl());
    map.addOverlay(createMarkerLast(40.8195,14.4248,0.18,-9,"2017/09/05 04:29:16.00",32069.695359945,743));
    map.addOverlay(createMarker(40.8213,14.4270,0.08,0.0,"2016/09/07 00:08:32.72",31410913.69536,0));
    map.addOverlay(createMarker(40.8193,14.4342,0.34,-0.4,"2016/09/09 00:25:40.26",31237085.69536,1));
    map.addOverlay(createMarker(40.8225,14.4298,0.12,-0.2,"2016/09/09 01:43:13.46",31232432.69536,2));
    map.addOverlay(createMarker(40.8170,14.4267,0.24,-0.2,"2016/09/09 02:50:35.54",31228390.69536,3));
    map.addOverlay(createMarker(40.8198,14.4260,0.12,0.1,"2016/09/09 04:12:18.74",31223487.69536,4));
    map.addOverlay(createMarker(40.8183,14.4235,0.30,0.2,"2016/09/09 21:49:15.42",31160070.69536,5));
    map.addOverlay(createMarker(40.8175,14.4257,0.18,0.9,"2016/09/09 21:55:0.33",31159725.69536,6));
    map.addOverlay(createMarker(40.8210,14.4252,0.25,0.4,"2016/09/10 15:11:56.86",31097509.69536,7));
    map.setMapType(G_PHYSICAL_MAP);"$

    Dim rx As RegexBuilder
    rx.Initialize.AppendEscaped(
    "map.addOverlay(").Append(rx.CharAny).AppendAtLeastOne.AppendEscaped(");")
    Dim m As Matcher = Regex.Matcher(rx.Pattern, test)
    Do While m.Find
       
    Log(m.Match)
    Loop
     
    MarcoRome likes this.
  5. Erel

    Erel Administrator Staff Member Licensed User

    BTW, the reason that the above pattern works is that CharAny (.) doesn't match end of line characters.
     
    MarcoRome likes this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice