B4A Library [B4X] RegexBuilder - Builder for Regular Expressions

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:
Key=Value
B4X:
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:
B4X:
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.
B4X:
Dim s As String = $",./;'\=""d23df""$
Log(Regex.IsMatch(rx.Clear.AppendEscaped(s).Pattern, s)) 'true
 

Attachments

MarcoRome

Expert
Licensed User
Yes. Agree ( very nice ) .

I have this text:

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);"$
and i want only this text:

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));
What i use this new class ?
Is it possible a little example ?
Thanks
 

Erel

Administrator
Staff member
Licensed User
B4X:
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
 

Erel

Administrator
Staff member
Licensed User
BTW, the reason that the above pattern works is that CharAny (.) doesn't match end of line characters.
 
Top