i have an array of words
i want to match all with starting '___'
but some words also having '___' at the end .
but i do not want to match these words
here is my word list
___apis
___db_tables
___groups
___inbox_messages
___sent_messages
___todo
___users
___users_groups
____4underscorestarting
sinan
sssssssssss
test_______dfg
testttttt
tet____
tttttttttt
uuuuuuuu
vvvvvvvvvvvv
wwwwwwww
zzzzzzzzzz
i want to match only these words
___apis
___db_tables
___groups
___inbox_messages
___sent_messages
___todo
___users
___users_groups
i do not want to match these words
tet____
test_______dfg
____4underscorestarting
this is how it looks like when i try
The solution using preg_grep function:
// $arr is your initial array of words
$matched = preg_grep("/^_{3}[^_].*/", $arr);
print_r($matched);
The output:
Array
(
[0] => ___apis
[1] => ___db_tables
[2] => ___groups
[3] => ___inbox_messages
[4] => ___sent_messages
[5] => ___todo
[6] => ___users
[7] => ___users_groups
)
Update: To get the opposite matches use one of the following:
regex pattern:
/^(?!_{3})\w*/
set the third argument of preg_grep function as PREG_GREP_INVERT(... preg_grep("/^_{3}[^_].*/", $arr, PREG_GREP_INVERT))
http://php.net/manual/en/function.preg-grep.php
^___[a-z].*
this should do it for you.See demo.
https://regex101.com/r/hHRg8d/1
^_{3}.*[^(_{3})]$
Starts(^) with 3 '_' _{3}
Can contain anything in the middle .*
Does not end($) in 3 '' [^({3}]
Related
I have an array variable which contain values like this:
$items = array(
"tbFrench",
"eaItaly1",
"discount21",
"kkMM5",
"NbndA",
"fcMNSS334"
);
i nedd to remove last character of string from this array values if the last character contain number, for example:
$newItems = array();
foreach($items as $item){
$newItems[] = $this->removeLastCharacter($item);
}
print_r($newItems);
....
function removeLastCharacter($string){
// ????
}
i want the result to look like this when i print_r the $newItems variable:
Array ( [0] => tbFrench [1] => eaItaly [2] => discount2 [3] => kkMM [4] => NbndA [5] => fcMNSS33 )
You could use regular expressions to remove the last digit.
function removeLastCharacter($string){
return preg_replace('[\d$]', '', $string);
}
\d matches every digit and $ references the end of the string. So this will only replace the last character if it is a digit at the end.
You can do a RegEx replacement over all the items in an array by simply providing the array as the subject, like so:
$items = preg_replace('/^d$/', '', $items);
There's no need to put it into a function at all - print_r($items) outputs:
Array
(
[0] => tbFrench
[1] => eaItaly
[2] => discount2
[3] => kkMM
[4] => NbndA
[5] => fcMNSS33
)
If you want to replace all trailing digits you can use /^\d+$/
Give a try with below code if it solve your problem
$items = array(
"tbFrench",
"eaItaly1",
"discount21",
"kkMM5",
"NbndA",
"fcMNSS334"
);
$newArr=array();
foreach($items as $item){
$data = preg_replace('[\d$]','',$item);
array_push($newArr,$data);
}
print_r($newArr);
Why not simply?
print_r( preg_replace( '/\d+$/', "", $items ) ); // preg_replace accepts an array as argument, pass yours directly, no need for a loop.
Array
(
[0] => tbFrench
[1] => eaItaly
[2] => discount
[3] => kkMM
[4] => NbndA
[5] => fcMNSS
)
Regex Explanation:
\d+ — matches a digit (equal to [0-9])
+ Quantifier — Matches between one and unlimited times, as many times as possible, giving back as needed (greedy)
$ — asserts position at the end of a line
There is a quick trick using rtrim.
$result = rtrim($str,"0..9");
second argument is a range using 2 dots ".."
You are done !!!
I have a string like this:
string="59|https://site59.com20|https://site20.com30|https://site30.com16|https://site15.com66|https://site66.com29|https://site29.com";
-Just one example is not just that.
I did this regular expression
preg_match_all("/[0-9][0-9](?:\|)(?:https\:\/\/)(.*?)/", string, string2);
But it only takes number|https:
I wonder how do I get it and only stop when you find the next occurrence of the regular expression and separate it into different arrays
Try this:
$string="59|https://site59.com20|https://site20.com30|https://site30.com16|https://site15.com66|https://site66.com29|https://site29.com";
preg_match_all("/(?:[0-9][0-9](?:\|)(?:https\:\/\/)(.*?)(?=[\d][\d]\||$))|([\d][\d]\|.*)/", $string, $matches);
Results array in $matches:
[0] => 59|https://site59.com
[1] => 20|https://site20.com
[2] => 30|https://site30.com
[3] => 16|https://site15.com
[4] => 66|https://site66.com
[5] => 29|https://site29.com
Try using preg_split
<?php
$string="59|https://site59.com20|https://site20.com30|https://site30.com16|https://site15.com66|https://site66.com29|https://site29.com";
$sites = preg_split("/[0-9][0-9](?:\|)(?:https\:\/\/)(.*?)/", $string);
foreach($sites as $site){
echo "https://$site\n";
}
https://site59.com
https://site20.com
https://site30.com
https://site15.com
https://site66.com
https://site29.com
I have a regex code that splits strings between [.!?], and it works, but I'm trying to add something else to the regex code. I'm trying to make it so that it doesn't match [.] that's between numbers. Is that possible? So, like the example below:
$input = "one.two!three?4.000.";
$inputX = preg_split("~(?>[.!?]+)\K(?!$)~", $input);
print_r($inputX);
Result:
Array ( [0] => one. [1] => two! [2] => three? [3] => 4. [4] => 000. )
Need Result:
Array ( [0] => one. [1] => two! [2] => three? [3] => 4.000. )
You should be able to split on this:
(?<=(?<!\d(?=[.!?]+\d))[.!?])(?![.!?]|$)
https://regex101.com/r/kQ6zO4/1
It uses lookarounds to determine where to split. It looks behind to try to match anything in the set [.!?] one or more times as long as it isn't preceded by and succeeded by a digit.
It also won't return the last empty match by ensuring the last set isn't the end of the string.
UPDATE:
This should be much more efficient actually:
(?!\d+\.\d+).+?[.!?]+\K(?!$)
https://regex101.com/r/eN7rS8/1
Here is another possibility using regex flags:
$input = "one.two!three???4.000.";
$inputX = preg_split("~(\d+\.\d+[.!?]+|.*?[.!?]+)~", $input, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
print_r($inputX);
It includes the delimiter in the split and ignores empty matches. The regex can be simplified to ((?:\d+\.\d+|.*?)[.!?]+), but I think what is in the code sample above is more efficient.
Hi I have a problem with my regex pattern:
preg_match_all('/!!\d{3}/', '!!333!!333 !!333 test', $result);
I want this to match !!333 but not !!333!333. How can I modify this regex to match only a max length of 5 characters - two ! and three numbers.
/^!!\d{3}$/
You need the anchors ^, that match the beginning of a string and $ for the end. Its like saying: "It must begin at the start of the string and it must end at the end of it." If you omit one (or both) the pattern allows arbitrary symbols at the beginning and/or the end.
Update
As I found out in the comments the question was very misleading. Now I suggest to split the string before applying the pattern
$string = '!!333!!333 !!333 test';
$result = array();
foreach (explode(' ', $string) as $index => $item) {
if (preg_match('/^!!\d{3}$/', $item)) {
$result[$index] = $item;
}
}
This also respects the index of the item. If you dont need it, remove the $index stuff or just ignore it ;)
Its much easier then trying to find a pattern, that fulfill your request all at once.
^!!\d{3}$
You need to anchor your pattern.
If you want to match a string with !!333 in it, you may want something like:
(^|\s)!!\d{3}($|\s)
With further explanation we can have a further refinement:
(^|\s)!!\d{3}(?=$|\s)
Which will not capture the trailing space allowing multiple matches in the same line to match one after another.
I find the easiest and most descriptive way to do this is with negative lookaheads and lookbehinds.
See:
preg_match_all('/(?<![^\s])!!\d{3}(?![^\s])/', '!!333 !!333!!333 !!333 test !!333', result);
This says: match anything of the form !![0-9][0-9][0-9] which doesn't have anything other than a space in front or behind it. Note that these lookaheads/lookbehinds aren't matched themselves, they are "zero-width assertions", they are thrown away and so you only get "!!333" etc in your match, not " !!333" etc.
It returns
[0] => Array
(
[0] => !!333
[1] => !!333
[2] => !!333
)
)
Also
preg_match_all(
'/(?<![^\s])!!\d{3}(?![^\s])/',
'!!333 !!555 !!333 !!123 !!555 !!456 !!333 !!333 !!444 !!444 !!123 !!123 !!123!!123',
$result));
returns
[0] => Array
(
[0] => !!333
[1] => !!555
[2] => !!333
[3] => !!123
[4] => !!555
[5] => !!456
[6] => !!333
[7] => !!333
[8] => !!444
[9] => !!444
[10] => !!123
[11] => !!123
)
That is, all but the last two which are too long.
See Lookahead tutorial.
Is it possible to make two matches of text - /123/123/123?edit
I need to match 123, 123 ,123 and edit
For the first(123,123,123): pattern is - ([^\/]+)
For the second(edit): pattern is - ([^\?=]*$)
Is it possible to match in one preg_match_all function, or I need to do it twice - one time for one pattern, second one for second?
Thanks !
You can do this with a single preg_match_all call:
$string = '/123/123/123?edit';
$matches = array();
preg_match_all('#(?<=[/?])\w+#', $string, $matches);
/* $matches will be:
Array
(
[0] => Array
(
[0] => 123
[1] => 123
[2] => 123
[3] => edit
)
)
*/
See this in action at http://www.ideone.com/eb2dy
The pattern ((?<=[/?])\w+) uses a lookbehind to assert that either a slash or a question mark must precede a sequence of word characters (\w is a shorthand class equivalent to [a-z0-9_]).