regex to match 3 parts from a given string - php

Example input:
hjkhwe5boijdfg
I need to split this into 3 variables as below:
hjkhwe5 (any length, always ends in some number (can be any number))
b (always a single letter, can be any letter)
oijdfg (everything remaining at the
end, numbers or letters in any combination)
I've got the PHP preg_match all setup but have no idea how to do this complex regex. Could someone give me a hand?

Have a try with:
$str = 'hjkhwe5boijdfg';
preg_match("/^([a-z]+\d+)([a-z])(.*)$/", $str, $m);
print_r($m);
output:
Array
(
[0] => hjkhwe5boijdfg
[1] => hjkhwe5
[2] => b
[3] => oijdfg
)
Explanation:
^ : begining of line
( : 1rst group
[a-z]+ : 1 or more letters
\d+ : followed by 1 or more digit
) : end of group 1
( : 2nd group
[a-z] : 1 letter
) : end group 2
( : 3rd group
.* : any number of any char
) : end group 3
$

You can use preg_match as:
$str = 'hjkhwe5boijdfg';
if(preg_match('/^(\D*\d+)(\w)(.*)$/',$str,$m)) {
// $m[1] has part 1, $m[2] has part 2 and $m[3] has part 3.
}
See it

Related

How to get special part of URL using preg_match?

I have an url like this one,
https://example.com/folder-name/article-name-xxx-xxx-xxx-xxx-xxx-xxx-5b5964935583202d2beff315.html#id-41
What I'm trying to do is get 5b5964935583202d2beff315 and 41 in url.
I really want to know how to do this, and I needs help. Your help would be greatly appreciated!
$url = "https://example.com/folder-name/dien-hy-cong-luoc-story-of-yanxi-palace-5b5964935583202d2beff315.html#id-41";
preg_match("/^.+-([^.-]+)\.html#id-(\d+)/", $url, $matches);
print_r($matches);
Output:
Array
(
[0] => https://example.com/folder-name/dien-hy-cong-luoc-story-of-yanxi-palace-5b5964935583202d2beff315.html#id-41
[1] => 5b5964935583202d2beff315
[2] => 41
)
Explanation:
/ : regex delimiter
^ : beginning of line
.+ : 1 or more any character but newline
- : a dash
([^.-]+) : group 1, 1 or more any character that is not a dot or dash
\. : a dot
html#id- : literally
(\d+) : group 2, 1 or more digits
/

Validate url parameters with preg_match

Valid example
12[red,green],13[xs,xl,xxl,some other text with chars like _&-##%]
number[anythingBut ()[]{},anythingBut ()[]{}](,number[anythingBut ()[]{},anythingBut ()[]{}]) or nothing
Full match 12[red,green]
Group 1 12
Group 2 red,green
Full match 13[xs,xl,xxl,some other text with chars like _&-##%]
Group 1 13
Group 2 xs,xl,xxl,some other text with chars like _&-##%
Not valid example
13[xs,xl,xxl 9974-?ds12[dfgd,dfgd]]
What I tried is this: (\d+(?=\[))\[([^\(\[\{\}\]\)]+)\], regex101 link with what I tried, but this also matches wrong input like given in the example.
If you just need to validate the input, you can add some anchors:
^(?:\d+\[[^\(\[\{\}\]\)]+\](?:,|$))+$
Regex101
If you also need to get all the matching parts, you can use another regex. Using only one will not work well.
$in = '12[red,green],13[xs,xl,xxl,some other text with chars like _&-##%],13[xs,xl,xxl 9974-?ds12[dfgd,dfgd]]';
preg_match_all('/(\d+)\[([^][{}()]+)(?=\](?:,|$))/', $in, $matches);
print_r($matches);
Output:
Array
(
[0] => Array
(
[0] => 12[red,green
[1] => 13[xs,xl,xxl,some other text with chars like _&-##%
)
[1] => Array
(
[0] => 12
[1] => 13
)
[2] => Array
(
[0] => red,green
[1] => xs,xl,xxl,some other text with chars like _&-##%
)
)
Explanation:
/ : regex delimiter
(\d+) : group 1, 1 or more digits
\[ : open square bracket
( : start group 2
[^][{}()]+ : 1 or more any character that is not open or close parenthesis, brackets or square brackets
) : end group 2
(?= : positive lookahead, make sure we have after
\] : a close square bracket
(?:,|$) : non capture group, a comma or end of string
) : end group 2
/ : regex delimiter

Regular expression to fetch all # mentioned user data from a string in PHP

I have below string. This string having data (#[ID:username__FULLNAME]) of three users mentioned. I want to extract them. I have tried below code but not getting desired results.
ID is integer type
username and FULLNAME may contain numbers, letter and all kind of special chars.
$t = 'Hi #[4232:mark__MΛRK ATTLEY] how are you ?
Hi #[4232:ryan__RYΛN вυηту] how are you ?
Hi #[4232:david__DΛVID शाहिद ] how are you ?
';
My PHP CODE:
$pattern = "|(?:(#\[[0-9]+:[\s\S(?!\])]+\]*))|";
preg_match_all($pattern, $string, $mentionList, PREG_PATTERN_ORDER);
print_r($mentionList);
Current Result:
Array
(
[0] => Array
(
[0] => #[4232:mark__MΛRK ATTLEY] how are you ?
Hi #[4232:ryan__RYΛN вυηту] how are you ?
Hi #[4232:david__DΛVID शाहिद] how are you ?
)
[1] => Array
(
[0] => #[4232:mark__MΛRK ATTLEY] how are you ?
Hi #[4232:ryan__RYΛN вυηту] how are you ?
Hi #[4232:david__DΛVID शाहिद] how are you ?
)
)
Expected Result:
Array
(
[0] => Array
(
[0] => #[4232:mark__MΛRK ATTLEY]
[1] => #[4232:ryan__RYΛN вυηту]
[2] => #[4232:david__DΛVID शाहिद ]
)
)
Can someone help me getting the desired results?
Thanks.
You can use the following regex: #\[.+\] (demo) that gets you all you have in [] plus the front #.
Check this working php demo
You can use this regex with 3 captured groups:
/#\[(\d+):(\S+)\h+(\S+)\h*\]/
RegEx Demo
RegEx Explanation:
#: Match literal #
\[: Match literal [
(\d+): Match 1+ digits and capture it in group #1 for id
:: Match literal :
(\S+): Match 1+ non-whitespace characters and capture it in group #2 for firstName
\h+: Match 1 or more horizontal whitespaces
(\S+): Match 1+ non-whitespace characters and capture it in group #3 for lastName
\h*: Match 0 or more horizontal whitespaces
\]: Match literal ]
Not sure if this will give you the exact output you are looking for, but yor regex is a bit too greedy. You can simplify it like this: (?:#\[[0-9]+.+?])
This should return the captured groups separately.
Not sure if the anonymous capture group is needed so it could be simplified down to (#\[[0-9]+.+?]) or possibly even (#\[.+?]).

How to make a regular expression in preg_match_all "and" [duplicate]

This question already has answers here:
php preg_match, matching when 2 words might come in random sequence
(2 answers)
Closed 6 years ago.
How to make a regular expression in preg_match_all "and"?
The mouse to nibble the cork from the bottle russia king.
$n = preg_match_all("/cork&bottle/i", mb_strtolower($y['foo'], 'UTF-8'), $matches);
/cork&bottle/i Does not work
This is the way I'd use:
$string = 'The mouse to nibble the cork from the bottle russia king.';
preg_match_all("/^(?=.*(cork))(?=.*(bottle))/i", $string, $matches);
print_r($matches);
Output:
Array
(
[0] => Array
(
[0] =>
)
[1] => Array
(
[0] => cork
)
[2] => Array
(
[0] => bottle
)
)
Explanation:
/ : regex delimiter
^ : begining of line
(?= : start lookahead
.* : 0 or more any character
(\bcork\b) : capture group #1 that contains "cork" with word boundaries
) : end of look ahead
(?= : start lookahead
.* : 0 or more any character
(\bottle\b) : capture group #2 that contains "bottle" with word boundaries
) : end of look ahead
/i : regex delimiter, case insensitive

PHP regex incorrect

I am trying to extract all strings that look like 12-15 from a parent string. This means all strings that have a dash in between two digits.
Using this answer as a basis, I tried the following:
<?php
$str = "34,56,67-90,45";
preg_match('/^(\d-\d)|(,\d-\d)|(\d-\d,)|(,\d-\d,)$/', $str, $output, PREG_OFFSET_CAPTURE);
echo print_r($output);
?>
This looks for any substring that looks a dash enclosed between digits, whether it has a comma before, after, or both, or none. When I run the PHP code, I get an empty array. On Regex101, when I test the regular expression, strings like 4-5,,,,, seem to, and I'm not understanding why it's letting me add extra commas.
What's wrong with my regex that I get an empty array?
I think you could use a simple regex like this
\d+[-]\d+
That is (match at least 1 digit) (match a literal dash) (match at least 1 digit)
\d matches a single digit. All the numbers in your sample string have two digits. You should use \d+ to match any number of digits.
preg_match('/^(\d+-\d+)|(,\d+-\d+)|(\d+-\d+,)|(,\d+-\d+,)$/', $str, $output, PREG_OFFSET_CAPTURE);
Output:
Array
(
[0] => Array
(
[0] => ,67-90
[1] => 5
)
[1] => Array
(
[0] =>
[1] => -1
)
[2] => Array
(
[0] => ,67-90
[1] => 5
)
)
You can also simplify the regexp:
preg_match('/(?:^|,)\d+-\d+(?:,|$)/', $str, $output, PREG_OFFSET_CAPTURE);
Output:
Array
(
[0] => Array
(
[0] => ,67-90,
[1] => 5
)
)
The | has precedence, meaning your expression is interpreted as "MATCH EITHER ONE OF THE FOLLOWING:
START of text -> 1 digit -> dash -> 1 digit (not matching end of text)
Comma (may be in the middle of the text, anywhere) -> 1 digit -> dash -> 1 digit
1 digit (anywhere) -> dash -> 1 digit -> comma
comma (anywhere) -> 1 digit -> dash -> 1 digit -> comma -> END of text
Also, your are using \d which matches 1 digit (only one character). You can use \d{2} to match 2 digits (00 to 99), or \d+ to match any integer (1, 55, 123456, etc).
In your case, I think you're trying to use this expression:
/(?:^|,)(\d+-\d+)(?=,|$)/
which means: START of text OR comma -> any integer -> dash -> any integer -> followed by (but not consuming inmatch) a comma OR END of text

Categories