How can I add optional validation patten in preg_match? - php

I'm try to use preg_match to parse the line. But, couldn't get the result correctly.
I want to parse those lines with optional // char.
Basic idea is some lines may contain //0016OIXXXXXXX (//4 digit and 9 str) and some line may not contain (//4 digit and 9 str).
Next line \n is mandatory.
Here are some sample lines;
Line 1
1812121212DD2220,31NTRFNONREF
502?102330
Line 2
1811091109CD20693,12NTRFRMSOIC110871941//0016RFXXXXXXX
206?000801
Here is my patten;
/(\d{6})((\d{2})(\d{2}))?(C|D)([A-Z]?)([0-9,]{1,15})([A-Z]{1,4})([A-Z a-z 0-9]{1,16})(\/\/)([0-9A-Z]{1,16})(\s*\n)([0-9]{1,3})(\?)([0-9]{0,6})/
Current patten can only work with //. If without //, patten is broken and can't parse the line.
I don't know how should I add (\/\/)([0-9A-Z]{1,16}) as optional patten.
Thanks in advance
:)

Just make the optional part well... optional:
\d{6}(?:\d{4})?[CD][A-Z]?[0-9,]{1,15}[A-Z]{1,4}[A-Za-z0-9 ]{1,16}(?:\/\/[0-9A-Z]{1,16})?\s*\n[0-9]{1,3}\?[0-9]{0,6}
// ^^^^^^^^^^^^^^^^^^^^^^^
I've removed the capture groups for lisibility, if you really want to keep them:
(\d{6})((\d{2})(\d{2}))?(C|D)([A-Z]?)([0-9,]{1,15})([A-Z]{1,4})([A-Za-z0-9 ]{1,16})(?:(\/\/)([0-9A-Z]{1,16}))?(\s*\n)([0-9]{1,3})(\?)([0-9]{0,6})
DEMO

If Am I understanding right your question.
Please, try to use or expression between the groups and validate any you case.
For example
`(pattern1) | (pattern-2) | ( (pattern3) | (pattern 4) )`
Please, try to consider using the | expression.

Related

Combine two regular expressions for php

I have these two regular expression
^(((98)|(\+98)|(0098)|0)(9){1}[0-9]{9})+$
^(9){1}[0-9]{9}+$
How can I combine these phrases together?
valid phone :
just start with : 0098 , +98 , 98 , 09 and 9
sample :
00989151855454
+989151855454
989151855454
09151855454
9151855454
You haven't provided what passes and what doesn't, but I think this will work if I understand correctly...
/^\+?0{0,2}98?/
Live demo
^ Matches the start of the string
\+? Matches 0 or 1 plus symbols (the backslash is to escape)
0{0,2} Matches between 0 and 2 (0, 1, and 2) of the 0 character
9 Matches a literal 9
8? Matches 0 or 1 of the literal 8 characters
Looking at your second regex, it looks like you want to make the first part ((98)|(\+98)|(0098)|0) in your first regex optional. Just make it optional by putting ? after it and it will allow the numbers allowed by second regex. Change this,
^(((98)|(\+98)|(0098)|0)(9){1}[0-9]{9})+$
to,
^(?:98|\+98|0098|0)?9[0-9]{9}$
^ this makes the non-grouping pattern optional which contains various alternations you want to allow.
I've made few more corrections in the regex. Use of {1} is redundant as that's the default behavior of a character, with or without it. and you don't need to unnecessarily group regex unless you need the groups. And I've removed the outer most parenthesis and + after it as that is not needed.
Demo
This regex
^(?:98|\+98|0098|0)?9[0-9]{9}$
matches
00989151855454
+989151855454
989151855454
09151855454
9151855454
Demo: https://regex101.com/r/VFc4pK/1/
However note that you are requiring to have a 9 as first digit after the country code or 0.

RegEx Or and AND

Hi I tired to use RegEx in PHP. The following elements I like to get with it:
<a="300">
<a="300"b="300">
<b="300">
The Problem is that I get only
<a="300">
<b="300">
with the following RegEx:
<(a|b)="[0-9]*">
What do I have to change, that I get all three elements? Is there a ANDOR operator?
Assuming your problem is rather a simple string processing than serious parsing, I would modify your regex like this:
<(a|b)="[0-9]+".*>
I added .* to allow characters inbetween " and >.
or a slightly my-flavored version:
<[ab]="\d+"[^>]*?>
piping single characters with | are less favored over [...]
\d is for series of digits
[^>]*? for characters other than >
You need an additional grouping, to specify, that you would accept multiple of that kind:
echo '<a="300">
<a="300"b="300">
<b="300">' | egrep '<((a|b)="[0-9]*")+>'
<a="300">
<a="300"b="300">
<b="300">
Regex is not boolean logic. The | symbol in regex is not an OR operator; it is referred to as alternation, which works similarly but is not quite the same thing. If you're just trying to match one of multiple characters, you should use square brackets [] to create a character set. In this case, [ab] matches a or b, just as [0-9] matches 0 or 1 or 2 etc.
Here's the pattern that I would suggest
<[ab]="\d+"(?:[ab]="\d+")?>

12 digit Regex for Phone number

I an trying to get a regex for a phone number with exactly 12 digits in the format: +############.
Code i am trying to use is ([+]?)\d{12}(\d{2})?$ but no luck.
Please help
This pattern will match exactly 12 digits after a plus sign:
/^\+\d{12}$/
What is your trailing optional (/d{2})? component doing in your pattern?
This is the same functionality without regex:
$phone='+012345678912';
if($phone[0]=='+' && strlen($phone)==13 && is_numeric(substr($phone,1))){
echo 'valid';
}else{
echo 'invalid';
}
// displays: valid
Try this:
^\+\d{12}(\d{2})?$
You needed to escape the plus sign
Regex101 Demo
Do we need to capture certain digits/sequences or are you just validating its a number with that format?
I use this online tool regex101 whenever I'm unsure of regex. It shows on the right exactly what you're capturing/checking which is very useful. Depending on your use case, I don't see how this regex doesn't work, please provide an example. Otherwise:
You're only capturing the + sign and the 2 digits after the initial 12.
You anchor to the end of the string and not the beginning
Both the + and 2 extra numerals are optional but you wanted to get the +############ exact?
I suggest you use \+(\d{12}) and avoid using anchors and capture groups you do not require.
If you want to support optional spaces between sets of three numbers, you would use this regex instead
^(\+)(\d{3}\s?){4}(\d{2})?$
where \s is a space character and ? means optional
https://regex101.com/r/nX5XnH/3 (demo)
+012 345 678 912 (ok)
+012345 678 912 (ok)
+012 345678912 (ok)
+01234567891244 (ok)
012345678913 (no mach - missing plus sign)

Regex isn't working properly with PHP or not getting how to implement this

There is something really I couldn't understand is how can I check my previous match with the next character and set starting and ending character please guys help me.
Here is an Example of my string
..A..B..A...B.A.B
What I'm trying to do is starting of string:
1=> Check the first character is .. or A
2=> and the Second thing is String cannot be like this ..A..A it must be like ..A..B.. and sequence.
3=> Ending character must be .. or B and won't be A
However, I can match the first character like so ^([A]{1}|[.]{1,100}) But when I'm trying this same way with ending character it is not working and I'm not getting how to do the step 2.
Save my day guys. Thanks
Failed Regex: ^[\.{1,40}|A{1}]+(?!A)+(B)+(?!B)+(B|\.{1,40})$
This regex should match the description you've given:
^(?:\.+?)?(A\.+?B\.?|\.\.)+$
^ is the start of the string (or line if m modifier is used).
(?:\.+?)? is one or more ., but it optional.
A\.+B\.? is looking for an A any amount of .s then a B and an optional ..
| is an alternative pattern we'll look at
\.\. are 2 .s
+ allows for the whole group to occur once or more
$ is the end of the string (or line, again depends on modifier being used)
Demo: https://regex101.com/r/OUJxxc/3/ (Probably with a clearer description than I provided)

RegExp Match PHP

Data:
N15319542045C13_1_3/61488007C13-130083_1_3/61488007C13-130083-1_1_3/P1197443641_1_3SD|1
NP1196939393_1_3SU|OD=2/7;|BNP1196939393_1_3SU|OD=2/7;|BNP1196930222_1_3SU|OD=4/11;|
NP1196930222_1_3SU|OD=4/11;|
N15319384625C13_1_3/61445794C13-130077_1_3SD||BN15319384625C13_1_3/61445794C13-130077_1_3SD||
RegExp:
(N(.*?)S([UID])\|(.*?))(?:B|\|.?$)
I am trying to find 7 matches using above regex but only 6 are matching. Not sure how to fix to match 1st line as well.
Format:
N(key)S(action)|(value or end)
end depend on different matches
I solved it if someone else needs:
(\x15(.*?)\x01([UID])\|(.*?))(?:.*?\x08|.*\|?$)
The regex didn't work because after the S[UID] you expect 2 | as per the regex but in the first input string there is only one.
One fix is to make the second group optional and move out the string end anchor $
(N(.*?)S([UID])\|(.*?))(?:B|\|.?)?$
Regex Demo
Or may be more simpler as
N.*?S[UID]\|.*$
Regex Demo

Categories