Hello experts, I need your help.
I have this input and want to fill a dictionary.
The group names can be more or less.
My solution works, but is not well solved.
How can I make it better, which would be the question.
Thank you.
//text = "[)>@06@PTVK1281257@21P@3SID-214214@@"; should also possible empty string 21P is empty, no value however.
My trials
//[)>@06@PTVK1281257@2P@14D15072024@ZLevel34@KReceiver@16KEN-en@VRuvel@3SID-214214@Q456NAR@1ZGermanCreate@@
//P TVK1281257
//2P
//14D 15072024
//Z Level34
//K Receiver
//16K EN-en
//V Ruvel
//3S ID-214214
//Q 456NAR or only 456
//1Z GermanCreate
string regEx = @"1Z(?([A-Za-z0-9/_,#\:\%\-\*\+\.]{1,17}))|3S(?([A-Za-z0-90-9]{9}))|P(?([A-Z0-9]{10}))|2P(?([A-Z0-9]{20}))|14D(?([0-9]{7}))|Z(?([A-Za-z0-90-9]{2,22}))|K(?([A-Za-z0-90-9]{3}))|16K(?([A-Za-z0-90-9]{5}))|V(?([A-Za-z0-90-9]{5}))|Q(?([0-9]{3}))";
text = "[)>@06@PTVK1281257@2P66@14D15072024@ZLevel34@KReceiver@16KEN-en@VRuvel@3SID-214214@Q456NAR@1ZGermanCreate@@";
//text = "[)>@06@PTVK1281257@21P66777@3SID-214214@@";
//text = "[)>@06@PTVK1281257@21P@3SID-214214@@"; should also possible empty string
//Dictionary results =
//Regex.Matches(text, regEx).Cast().ToDictionary(ma => ma.Groups[1].Value, ma => ma.Groups[2].Value);
Dictionary results = new Dictionary();
Regex rgx = new Regex(regEx);
Match match = rgx.Match(text);
while (match.Success)
{
string[] names = rgx.GetGroupNames();
Console.WriteLine("Named Groups:");
foreach (var name in names)
{
Group grp = match.Groups[name];
Console.WriteLine(" {0}: '{1}'", name, grp.Value);
}
if (match.Groups["BatchId"].Name == "BatchId" && match.Groups["BatchId"].Value != "")
results.Add("BatchId", match.Groups["BatchId"].Value);
else if (match.Groups["IDCustom"].Name == "IDCustom" && match.Groups["IDCustom"].Value != "")
results.Add("IDCustom", match.Groups["IDCustom"].Value);
else if (match.Groups["ProductPartNumber"].Name == "ProductPartNumber" && match.Groups["ProductPartNumber"].Value != "")
results.Add("ProductPartNumber", match.Groups["ProductPartNumber"].Value);
else if (match.Groups["SupplierPartNumber"].Name == "SupplierPartNumber" && match.Groups["SupplierPartNumber"].Value != "")
results.Add("SupplierPartNumber", match.Groups["SupplierPartNumber"].Value);
else if (match.Groups["ManufactorDate"].Name == "ManufactorDate" && match.Groups["ManufactorDate"].Value != "")
results.Add("ManufactorDate", match.Groups["ManufactorDate"].Value);
else if(match.Groups["MSLClass"].Name == "MSLClass" && match.Groups["MSLClass"].Value != "")
results.Add("MSLClass", match.Groups["MSLClass"].Value);
else if (match.Groups["ArticleMaster"].Name == "ArticleMaster" && match.Groups["ArticleMaster"].Value != "")
results.Add("ArticleMaster", match.Groups["ArticleMaster"].Value);
else if (match.Groups["UnitCode"].Name == "UnitCode" && match.Groups["UnitCode"].Value != "")
results.Add("UnitCode", match.Groups["UnitCode"].Value);
else if(match.Groups["Vendor"].Name == "Vendor" && match.Groups["Vendor"].Value != "")
results.Add("Vendor", match.Groups["Vendor"].Value);
else if (match.Groups["Quantity"].Name == "Quantity" && match.Groups["Quantity"].Value != "")
results.Add("Quantity", match.Groups["Quantity"].Value);
match = match.NextMatch();
}
Thanks for your help!
Thomas AdlerPosted Mar 26, 2024, 3:04 PM
Hello Tuhin Paul,
Do you have another good tip for me?
Can you answer briefly yes or no? Would be super nice.
Regards Thomas
Thomas AdlerPosted Mar 19, 2024, 3:37 PM
Hello Paul,
Maybe you can help again, that would be great of you!
a) Problem with group zero.
b) With prefix, maybe it was a misunderstanding.
See the code and my goal.
Picture 1
Count from Dictionary is zero. Problem is the group "0"
Picture 2
Tuhin PaulPosted Mar 16, 2024, 6:18 PM
Your Questions:
Regex for Specific Lengths:
{5,22}: This specifies a range of characters, from 5 to 22 in this case.{4}: This specifies exactly 4 characters.*?: This matches zero or more repetitions of the preceding character.?alone is equivalent to{0,1}.Group Name "0":
Using Prefix as Output:
Try-Catch Block:
try-catchblock is indeed helpful. It catches exceptions like timeouts that might occur if the regex matching takes too long. Including it is a good practice.Output:
This code will produce the desired output:
Tuhin PaulPosted Mar 16, 2024, 6:18 PM
see the code:
prefix(A-Z0-9]{1,2}) for the one or two-letter prefix andvalue([A-Za-z0-9-]{0,22}) for any characters and hyphens up to 22 characters.Matchesmethod:rgx.Matches(text)to find all occurrences of the pattern in the string.match.Groups["prefix"].Valueandmatch.Groups["value"].Value.prefixas the key for theresultsdictionary, achieving the desired output format.Thomas AdlerPosted Mar 16, 2024, 7:54 AM
Hello Paul,
Current state, looks better, but not good. Thanks!
A few more small questions in advance.
I think my RegEx is relatively simple and simple.
If I want a string from to?
{5,22}
If I want to have exactly 4 numbers?
{4}
If I want to read any number of characters after the prefix?
{?} is it ? or *
The goal is
MSLClass: Level34
ArticleMaster: Receiver
BatchId: GermanCreate
and so one.
>You could consider wrapping the Regex.Matches call in a try-catch block to catch potential exceptions like invalid input format.
Can you implement this in your example, and how helpful is it?
The Dictionary results2 has only one item. Why?
Where does the group name 0 come from?
if (groupName == "0")
continue;
I use this. Is it good?
If I want to have the prefix instead of the group name. Can I read this out, perhaps use it additionally?
Sample: 3S instead IDCustom
Thank you very much for your answer and help.
Tuhin PaulPosted Mar 14, 2024, 7:28 PM
While the code handles empty values within the regex pattern, it doesn't explicitly handle potential errors during the matching process. You could consider wrapping the
Regex.Matchescall in atry-catchblock to catch potential exceptions like invalid input format.Tuhin PaulPosted Mar 14, 2024, 7:24 PM
See the code
Instead of iterating over group names separately, looped through them directly within the same loop.