-
Notifications
You must be signed in to change notification settings - Fork 0
Delimiter Regular Expression (drex)
- Namespace : HarkLib.Parsers.Generic
- File : HarkLib.Parsers.Generic.dll
A Delimiter Regular Expression is an expression similar to Regex but instead of specify what is inside each groups, we specify when it ends.
An easy way to parse a document is to use ByteSequencer.Parse
as shown below :
ParserResult root = ByteSequencer.Parse(
"[version: ][i/code: ][message:\r\n][<headers:\r\n\r\n>][name::][|value|:\r\n|$][</>][$s/body$]",
"HTTP/1.1 404 Not found\r\nHeader1: data1\r\nHeader2: data2\r\n\r\nHello! This is the body!"
).Close();
The Close()
call is not needed. If not provided, it will return a ByteSequencer
and implicitly cast it into a ParserResult
. This is similar to calling new ParserResult(byteSequencer.Document)
.
This call is trying to parse "HTTP/1.1 404 Not found\r\nHeader1: data1\r\nHeader2: data2\r\n\r\nHello! This is the body!"
with the drex "[version: ][i/code: ][message:\r\n][<headers:\r\n\r\n>][name::][|value|:\r\n|$][</>][$s/body$]"
.
Another way to use the parser is to create a ByteSequencer
object and call the functional equivalent as shown bellow :
ParserResult root = new ByteSequencer("HTTP/1.1 404 Not found\r\nHeader1: data1\r\nErrorHeader\r\nSet-Cookie: a=1\r\nSet-Cookie: b=2\r\nHeader2: data2\r\nErrorHeaderFinal\r\n\r\nHello! This is the body!")
.Until("version", " ")
.Until("code", " ", converter : s => int.Parse(s))
.Until("message", "\r\n")
.RepeatUntil("headers", "\r\n\r\n", b => b
.Or(bb => bb
.Until("name", ":", validator : s => !s.Contains("\r\n"))
.Until("value", "\r\n", converter : s => s.Trim()),
bb => bb
.Until("error", "\r\n"),
bb => bb
.ToEnd("final", converter : bs => bs.GetString())))
.ToEnd("body", converter : bs => bs.GetString())
.Close();
Keep in mind that drex uses these methods behind. So everything possible in drex is possible with methods, but if you want to have unhandled object types as results, you will have to use methods.
For such cases, you can use a mixed form as shown below :
ParserResult root = ByteSequencer.Parse(
"[version: ][i/code: ][message:\r\n]",
"HTTP/1.1 404 Not found\r\nHeader1: data1\r\nHeader2: data2\r\n\r\nHello! This is the body!")
.Until("message", "\r\n", converter : s => new MyObjectType(s)) // Creates a new object from the matched content
.Eval("[<headers:\r\n\r\n>][name::][|value|:\r\n|$][</>][$s/body$]");
You can find a short description for operations here :
Operation | Description |
---|---|
[version: ] |
Everything until : called version . |
[i/code: ] |
Everything until casted into int : called code . |
[message:\r\n] |
Everything until \r\n : called message . |
[<headers:\r\n\r\n>]...[</>] |
Repeat ... until \r\n\r\n : called headers. |
[name::] |
Everything until : : called name . |
`[ | value |
[$s/body$] |
Everything until the end of the sequence, casted into string : called body . |
`[$ | body |
`{[version: ] | |
`{[version: ] | |
[HeaderName:x!\r\n] |
HeaderName ends when a x is found and must not contain \r\n . |
[Name] |
Add an empty entry called Name . |
[ba/Name] |
Add an empty byte array entry called Name . |
[Name=Content here] |
Add an entry called Name with a value equals to Content here . |
[<Name>] |
Add an empty list entry called Name . |
You can specify the type of a content :
Input | Operation | Result |
---|---|---|
404 |
[code: ] |
"404" |
404 |
[s/code: ] |
"404" |
404 |
[bi/code: ] |
new BigInteger(404) |
404 |
[xi/code: ] |
1028 (4 * 16 * 16 + 0 * 16 + 4) |
404 |
[xbi/code: ] |
BigInteger.Parse("1028") |
404 |
[i/code: ] |
404 |
This is a text |
[$s/body$] |
"This is a text" |
" text " |
`[$ | body |
" 404 " |
`[$i/ | body |
The handled types are the following :
Symbol | Name | Type | Operation |
---|---|---|---|
i/ |
Integer | int | Parse |
b/ |
Byte | byte | Parse |
x/ |
Hexadecimal | int | Parse |
s/ |
String | string | Encode |
ba/ |
Byte array | byte[] | Encode or nothing |
bi/ |
BigInteger | BigInteger | Parse or initialize |
sm/ |
Stream | MemoryStream | Wrap or encode + wrap |
xbi/ |
Hexadecimal BigInteger | BigInteger | Parse |
ParserResult provides an easy way to browse into matched groups. You can find some examples below :
string version = (string)root["version"];
string version = root.GetString("version");
string version = root.Get<string>("version");
int code = (int)root["code"];
int code = root.Get<int>("code");
string value = root.Get<string>("headers.<0>.value");
string value = root.Get<string>("headers.<name=Header1>.value");
string value = root.Get<string>("headers.<|name=header1|>.value");
List<string> values = root.GetAll<string>("headers.<$name=Set-Cookie$>.value");
List<string> values = root.GetAll<string>("headers.<|$name=set-cookie$|>.value");
List<string> values2 = root.GetAll<string>("headers.<name=Header1>.value");
List<string> values2 = root.GetAll<string>("headers.<$name=Header1$>.value");
List<string> values2 = root.GetAll<string>("headers.<|name=Header1|>.value");
List<string> values2 = root.GetAll<string>("headers.<|$name=Header1$|>.value");
List<string> allValues = root.GetAll<string>("headers.<*>.value");
Documentation
- HarkLib.Parsers.Generic.dll
- HarkLib.Parsers.dll
- HarkLib.Security.dll
- HarkLib.Core.dll
- HarkLib.Net.dll
Classes
- HarkLib.Parsers.Generic
- HarkLib.Parsers
- HarkLib.Security
- HarkLib.Core
- HarkLib.Net