The Problem
I'll be extracting up to 4 parts of a String that come from user-input. All 4 parts need to be in order i.e. (1-4) below in that order
The first capturing group is required and the last few are not. The named capturing groups are described below
KEY
(This can be eitherCONF|ESD|TRACKING
and needs to be followed be either[:;'\s]\*s
) -- This group is requiredDATA
This can be any text except for any of the 2 patterns described below (Should assume multiple whitespace can lead this followingKEY
LINE_DATA
This is a string in the following kind of format"1,2,3"
or"1(2),3(4),5(6)"
and should account for spaces in between chars i.e." 1 ( 2 ) , 3(4 ), 5 6) "
This capture can only come after a match of"L[:';\s]\s*]"
...but I don't want to capture this part. I just want to capture the"1(2),3(4)..."
part (and exclude any trailing and leading whitespace).LINE_DATA
is optionalINITIALS
This is the last part of the string and would come before a\s*$
. It's a pattern that would be*[a-zA-Z]+
i.e."*sm", "*jdm", "*pL"
should all match. Again...this group can be optional too and I don't want any leading/trailing whitespace.
Note: this is all case-insensitive too.
Examples with expectations
INPUT:
"CONF: FEDEX 12345 L: 12(2),2(9),32 *SM"
MATCHES
[KEY=>'CONF' , DATA => 'FEDEX 12345', LINE_DATA => '12(2),2(9),32', INITIALS=>'*SM']
INPUT:
"ESD: 12/12/92"
MATCHES:
[KEY: 'ESD', DATA: '12/12/92']
INPUT:
"tRacking' my data L: 1,2,3(4) "
;MATCHES:
[KEY=>'tRacking', DATA=>'my data' LINE_DATA: '1,2,3(4)']
My regex is below
/^(?<KEY>CONF|ESD|TRACKING)[:;'\s]\s*(?<DATA>.*?)\s*(?:L[:;'\s]\s*\K(?<LINE_DATA>[\d\s,\(\)]+?))?\s*(?<INITIALS>\*[a-zA-Z]+)?\s*\K$/i
https://regex101.com/r/Sw8UXC/1 is an interactive playground with the regex.
What I'm looking for in review
- Are there any flaws with this regex and are there foreseeable issues where it would fail with what I need?
- Is there a way to simplify it further?
- Any other assumptions I should be making because this comes from user-input?
I'm a little unsure of the '\K
s, but it made it so that I only got the 4 parts I needed (i.e. no whitespace in between groups was also matched on (regardless of being captured)
\K
restarting the fullstring match. If you don't have any need for the fullstring match, then don't access the[0]
element in the generated array of matches. You only need to use\K
if you want to "forget/release" previously matched characters -- which you have no need for here. \$\endgroup\$[$1, ?[$2, ?[$3, ?[$4]]]
or?$1, ?$2, ?$3, ?$4
? In other words, can the 3rd capture group be satisfied without the 2nd? Can a valid/qualifying string contain only$1
and$4
? I'm trying to determine if I have maintained your pattern logic with regex101.com/r/Q8BvaP/1 \$\endgroup\$\K
. Makes sense. I put it in because it made the result 'cleaner' on the regex101 page. But won't make much difference in actual code. So --$3
and$4
can only exist if$2
does. We can have following permuatations$1 $2
$1 $2 $3
$1 $2 $3 $4
$1 $2 $4
\$\endgroup\$