PHP: Regular exp to get the last number from exactly string - php

I'm trying to get the string that match with original and with number in the end.
I got these strings:
mod_courts2
mod_courts_config
mod_courts_config2
From these strings I want the one that matches only with "mod_courts" with number in the end.
I'm doing this:
if (strpos($t, "mod_courts") !== FALSE) {
preg_match('/^\w+(\d+)$/U', $t, $match);
echo $match;
}
This returns me "mod_courts2" and "mod_courts_config2", I just want "mod_courts2"

Use the following regex:
/^[a-z]+_[a-z]+(\d+)$/
Explanation:
^ - assert position at the beginning of the string
[a-z]+ - match any alphabet one or more times
_ - match a literal undescore character
[a-z]+ - match any alphabet one or more times
(\d+) - match (and capture) any digit from 0 to 9 one or more times
$ - assert position at the end of the string
Test cases:
$array = array(
'mod_courts2',
'mod_courts_config',
'mod_courts_config2'
);
foreach ($array as $string) {
if(preg_match('/^[a-z]+_[a-z]+(\d+)$/i', $string, $matches)) {
print_r($matches);
}
}
Output:
Array
(
[0] => mod_courts2
[1] => 2
)

Very simply, you can do:
/^(mod_courts\d+)$/
However, if you want exactly the following format: sometext_somettext2, you can use the following regex:
/^([a-zA-Z]+_[a-zA-Z]+\d+)$/
or
/^([^_]+_[^_]+\d+)$/
Demos
http://regex101.com/r/jP8iC1
http://regex101.com/r/tI1uX8
http://regex101.com/r/fX8pO5

^mod_courts\d+$
this should do it

You can just use
^mod_courts[0-9]+$
Meaning mod_courts followed by a number (and only that, thanks to ^$ matching the beginning and end of the string). No need for the strpos check.

Related

Trying to create a regex in PHP that matches patterns inside a pattern

I have seen some regex examples where the string is "Test string: Group1Group2", and using preg_match_all(), matching for patterns of text that exists inside the tags.
However, what I am trying to do is a bit different, where my string is something like this:
"some t3xt../s8fo=123,sij(variable1=123,variable2=743,variable3=535)"
What I want to do is match the sections such as 'variable=123' that exist inside the parenthesis.
What I have so far is this:
if( preg_match_all("/\(([^\)]*?)\)"), $string_value, $matches )
{
print_r( $matches[1] );
}
But this just captures everything that's inside the parenthesis, and doesn't match anything else.
Edit:
The desired output would be:
"variable1=123"
"variable2=743"
"variable3=535"
The output that I am getting is:
"variable1=123,variable2=743,variable3=535"
You can extract the matches you need with a single call to preg_match_all if the matches do not contain (, ) or ,:
$s = '"some t3xt../s8fo=123,sij(variable1=123,variable2=743,variable3=535)"';
if (preg_match_all('~(?:\G(?!\A),|\()\K[^,]+(?=[^()]*\))~', $s, $matches)) {
print_r($matches[0]);
}
See the regex demo and a PHP demo.
Details:
(?:\G(?!\A),|\() - either end of the preceding successful match and a comma, or a ( char
\K - match reset operator that discards all text matched so far from the current overall match memory buffer
[^,]+ - one or more chars other than a comma (use [^,]* if you expect empty matches, too)
(?=[^()]*\)) - a positive lookahead that requires zero or more chars other than ( and ) and then a ) immediately to the right of the current location.
I would do this:
preg_match("/\(([^\)]+)\)/", $string_value, $matches);
$result = explode(",", $matches[1]);
If your end result is an array of key => value then you can transform it into a query string:
preg_match("/\(([^\)]+)\)/", $string_value, $matches);
parse_str(str_replace(',', '&', $matches[1]), $result);
Which yields:
Array
(
[variable1] => 123
[variable2] => 743
[variable3] => 535
)
Or replace with a newline \n and use parse_ini_string().

Get string with number of specified length

Supposing there's an array as the following:
$arr = array('foo1234bar', 'foo1234', '1234bar', 'foo12345bar');
and I just need the elements that contains 4 characters in total only. So except for foo12345bar, other 3 elements are valid.
Because '\d{4}' would match foo12345bar, so I try following clumsily:
$arr = array('foo1234bar', 'foo1234', '1234bar', 'foo12345bar');
$result = array();
foreach ($arr as $value) {
preg_match('/\d+/', $value, $match);
if (strlen($match[0]) != 4) {
continue;
}
$result[] = $value;
}
var_dump($result); //array('foo1234bar', 'foo1234', '1234bar')
Is there a regular expression to match directly(so the if condition can be omitted)? Thank you in advance.
This easy to handle with look-around regex and preg_grep function:
$arr = array('foo1234bar', 'foo1234', '1234bar', 'foo12345bar');
print_r(preg_grep('/(?<!\d)\d{4}(?!\d)/', $arr));
RegEx Breakup:
(?<!\d) # assert previous char is not a digit
\d{4} # match exact 4 digits
(?!\d) # assert next char is not a digit
Output:
Array
(
[0] => foo1234bar
[1] => foo1234
[2] => 1234bar
)
Assuming the characters in front of and after the numbers will always be alphabetical, you can use this regex:
^[a-zA-Z]*\d{4}[a-zA-Z]+$
Modify your regex as follows
/^\D*\d{4}\D*$/
Explaination
^ your string must start with
\D any non-digit char
* repeated from 0 to infinite times
\d{4} followed by any digit repeated EXACTLY 4 times
\D followed by any non-digit char
* repeated from 0 to infinite times
$ end of the string
Moreover you could modify your code as follows
$arr = array('foo1234bar', 'foo1234', '1234bar', 'foo12345bar');
$result = array_filter(
$arr,
function($element) {
return preg_match('/^\D*\d{4}\D*$/', $element);
}
);
var_dump($result);
 Pay attention
As OP didn't specify it, this regex will match even 1234 (any four digit string without non-digit chars in front or behind). If he wishes to have at least a char in front or/and behind, this regex must be changed.
the regexp will be \d{4}
preg_match('/\d{4}/', $value, $match);
expect will help
you might try folowing : preg_match('/\D\d{4}\D/', $value, $match); it searches for:
a not digit(/D)
4 digits(/d{4})
again a non digit(/D)
This regular expression will work on all your examples:
'/^\D*(\d{4})\D*$/'
││ │ │ └── end string
││ │ └───── zero or more NOT digits
││ └─────────── four digits ( match 1 )
│└─────────────── zero or more NOT digits
└──────────────── start string
They doesn't work if there are multiple number group in the string ( '123abc1234o' ).

find a specific word in string php

I have a text in PHP stored in the variable $row. I'd like to find the position of a certain group of words and that's quite easy. What's not so easy is to make my code recognize that the word it has found is exactly the word i'm looking for or a part of a larger word. Is there a way to do it?
Example of what I'd like to obtain
CODE:
$row= "some ugly text of some kind i'd like to find in someway"
$token= "some";
$pos= -1;
$counter= substr_count($row, $token);
for ($h=0; $h<$counter; $h++) {
$pos= strpos($row, $token, $pos+1);
echo $pos.' ';
}
OUTPUT:
what I obtain:
0 17 47
what I'd like to obtain
0 17
Any hint?
Use preg_match_all() with word boundaries (\b):
$search = preg_quote($token, '/');
preg_match_all("/\b$search\b/", $row, $m, PREG_OFFSET_CAPTURE);
Here, the preg_quote() statement is used to correctly escape the user input so as to use it in our regular expression. Some characters have special meaning in regular expression language — without proper escaping, those characters will lose their "special meaning" and your regex might not work as intended.
In the preg_match_all() statement, we are supplying the following regex:
/\b$search\b/
Explanation:
/ - starting delimiter
\b - word boundary. A word boundary, in most regex dialects, is a position between a word character (\w) and a non-word character (\W).
$search - escaped search term
\b - word boundary
/ - ending delimiter
In simple English, it means: find all the occurrences of the given word some.
Note that we're also using PREG_OFFSET_CAPTURE flag here. If this flag is passed, for every occurring match the appendant string offset will also be returned. See the documentation for more information.
To obtain the results you want, you can simply loop through the $m array and extract the offsets:
$result = implode(' ', array_map(function($arr) {
return $arr[1];
}, $m[0]));
echo $result;
Output:
0 18
Demo
What you're looking for is a combination of Regex with a word boundaries pattern and the flag to return the offset (PREG_OFFSET_CAPTURE).
PREG_OFFSET_CAPTURE
If this flag is passed, for every occurring match the appendant
string offset will also be returned. Note that this changes the
value of matches into an array where every element is an array
consisting of the matched string at offset 0 and its string offset
into subject at offset 1.
$row= "some ugly text of some kind i'd like to find in someway";
$pattern= "/\bsome\b/i";
preg_match_all($pattern, $row, $matches, PREG_OFFSET_CAPTURE);
And we get something like this:
Array
(
[0] => Array
(
[0] => Array
(
[0] => some
[1] => 0
)
[1] => Array
(
[0] => some
[1] => 18
)
)
)
And just loop through the matches and extract the offset where the needle was found in the haystack.
// store the positions of the match
$offsets = array();
foreach($matches[0] as $match) {
$offsets[] = $match[1];
}
// display the offsets
echo implode(' ', $offsets);
Use preg_match():
if(preg_match("/some/", $row))
// [..]
The first argument is a regex, which can match virtually anything you want to match. But, there are dire warnings about using it to match things like HTML.

How do i break string into words at the position of number

I have some string data with alphanumeric value. like us01name, phc01name and other i.e alphabates + number + alphabates.
i would like to get first alphabates + number in first string and remaining on second.
How can i do it in php?
You can use a regular expression:
// if statement checks there's at least one match
if(preg_match('/([A-z]+[0-9]+)([A-z]+)/', $string, $matches) > 0){
$firstbit = $matches[1];
$nextbit = $matches[2];
}
Just to break the regular expression down into parts so you know what each bit does:
( Begin group 1
[A-z]+ As many alphabet characters as there are (case agnostic)
[0-9]+ As many numbers as there are
) End group 1
( Begin group 2
[A-z]+ As many alphabet characters as there are (case agnostic)
) End group 2
Try this code:
preg_match('~([^\d]+\d+)(.*)~', "us01name", $m);
var_dump($m[1]); // 1st string + number
var_dump($m[2]); // 2nd string
OUTPUT
string(4) "us01"
string(4) "name"
Even this more restrictive regex will also work for you:
preg_match('~([A-Z]+\d+)([A-Z]+)~i', "us01name", $m);
You could use preg_split on the digits with the pattern capture flag. It returns all pieces, so you'd have to put them back together. However, in my opinion is more intuitive and flexible than a complete pattern regex. Plus, preg_split() is underused :)
Code:
$str = 'user01jason';
$pieces = preg_split('/(\d+)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE);
print_r($pieces);
Output:
Array
(
[0] => user
[1] => 01
[2] => jason
)

I need help applying a limit to a Regular expression on php

I am trying to find a number that consists of only 8 numbers, this is the code I have already:
preg_match_all("/([0-9]{8})/", $string, $match)
but this pulls 8 numbers from number strings that are longer than 8 digits
any help would be gratefully appreciated
Thanks
I'll use \d rather than [0-9].
If your string should contain nothing but a number of eight digits
Use ^ and $ to match start and end of string, respectively:
preg_match_all('/^(\d{8})$/', $string, $match)
If, within a larger string, you're matching a number that should have a maximum of eight digits
Quick but slightly brutish approach:
Use \D ([^0-9]) to match "not-a-number":
preg_match_all('/^|\D(\d{8})\D|$/', $string, $match)
Lookbehinds/lookaheads might make this better:
preg_match_all('/(?<!\d)(\d{8})(?!\d)/', $string, $match)
You need word boundaries
/\b[0-9]{8}\b/
Example:
$string = '34523452345 2352345234 13452345 45357567567567 24573257 35672456';
preg_match_all("/\b[0-9]{8}\b/", $string, $match);
print_r($match);
Output:
Array
(
[0] => Array
(
[0] => 13452345
[1] => 24573257
[2] => 35672456
)
)
This might be better than the other two suggestions:
preg_match_all('/(?<!\d)(\d{8})(?!\d)/', $string, $match)
Note that \d is equivalent to [0-9].
preg_match_all("/(?:^|\D)(\d{8})(?:\D|$)/", $string, $match);
Where the start and end non-matching groups (?:) allow for any non-digit (\D) or the start (^) or end ($) of the string.
Maybe include anything but digits before and after.
preg_match_all("/[^\d]([\d]{8})[^\d]/", $string, $match)

Categories