how to ignore a character in the regular expression - php

I do not know how to ignore an item from the ER.
just need to get P1, but this returns /P1.
is possible to just ignore the bar?
$pattern = "#(/P[0-9])?#";

There are two options here:
Exclude it from the group, P1 will be the contents in the capture group:
$pattern = "#/(P[0-9])#";
Use a lookbehind so that the / isn't even a part of the match, the entire match will be P1:
$pattern = "#(?<=/)P[0-9]#";
Note that I also removed the ? after your group because I don't think you actually want it, this makes the previous element optional so the regex (/P[0-9])? would match literal any string (it would match an empty string if /P[0-9] could not be matched).

With preg_* functions, you can use the \K trick that reset the begin of the match, example:
$pattern = '~/\KP[0-9]~';

Related

How to find and replace single quote in some string?

Because assert — Checks if assertion is FALSE in php after 7.2 version changed need using string as the assertion is DEPRECATED as of PHP 7.2.
And I want use replace in path php storm function with regex, changing all point where is it was, how it's look this is regular expression ?
example pioints:
assert('is_array($config)');
assert('is_string($location)');
assert('is_string($entityId)');
I just found and replace first quote, just like this
.*?(\bassert\('\b)[^$]* replace to assert(. But how it be with last quote I don't know.
result must be
assert(is_array($config));
assert(is_string($location));
assert(is_string($entityId));
with first single quote I found solution, need find solution to last single quote
Any ides ?
One option to match a single quote only could be to make use of \G to assert the position at the end of the previous match. Make use of \K to forget what was currently matched and then match the single quote.
In the replacement use an empty string.
(?:^.*?\bassert\(|\G(?!^))[^']*\K'(?=.*\);)
About the pattern
(?: Non capturing group
^.*?\bassert\( Match from the start of the string in a non greedy way until you encounter assert(
| Or
\G(?!^) Assert position at the previous match, not at the start
) Close non capturing group
[^']*\K' Match 0+ times not ', forget what was matched and match '
(?=.*\);) Assert what is on the right is a closing parenthesis and ;
Regex demo
Another way could be to use 3 capturing groups, match the ' that you want to remove and use the groups in the replacement:
^(.*?\bassert\()'([^']+)'(.*)$
Regex demo
We would better off starting with an expression with more boundaries, such as:
.*?(\bassert\b)\s*\(('|")\s*([^'"]*?)\s*('|")\s*\)\s*;
Test
$re = '/.*?(\bassert\b)\s*\((\'|")\s*([^\'"]*?)\s*(\'|")\s*\)\s*;/s';
$str = 'assert (" is_string($entityId)") ;';
$subst = '$1($3);';
echo preg_replace($re, $subst, $str);
The expression is explained on the top right panel of this demo, if you wish to explore further or modify it, and in this link, you can watch how it would match against some sample inputs step by step, if you like.

regex in url and xpath

I have used xpath to crawl all href value in a ul li a.
foreach ($domExemple as $exemple) {
$result[$i++] = $exemple->nodeValue;
}
Where $exemple->nodeValue is a string like /produit/3017620424403/nutella
I want to retrieve all number between the two /
They have different length...
I tried this regex : /\/([0-9]{0,})/i
But it returns not the good thing...
Anyone to explain me and help me ?
In your pattern you have to add the forward slash at the end as well:
/\/([0-9]{0,})\//i
^^
You don't have to escape the forward slash if you change to another delimiter like for example ~ and {0,} can be written as * but would also match an empty string. You might update it to use a + instead to match 1+ times a digit.
$pattern = "~/([0-9]+)/~i";
Your value is in the first capturing group. Note that there is no start boundary so if there are multiple parts in the string with /digits/ then those will also be matched.
Regex demo
Another option could be to match both forward slashes from the start of the string and make use of \K to forget what was matched. Then match 1+ digits and assert what is on the right is a /
^/[^/]+/\K\d+(?=/)
Regex demo
Assuming the URL is in the format provided above, try this:
#(/[0-9]*/)#
# are chosen as delimiters so we won't have to escape the slashes and have messy code.
If you want just the numbers, use this:
#/([0-9]*)/#
The paranthesis will group what you are looking for.

PHP/Laravel trim all but last word in a namespace

Trying to trim a fully qualified namespace so to use just the last word. Example namepspace is App\Models\FruitTypes\Apple where that final word could be any number of fruit types. Shouldn't this...
$fruitName = 'App\Models\FruitTypes\Apple';
trim($fruitName, "App\\Models\\FruitTypes\\");
...do the trick? It is returning an empty string. If I try to trim just App\\Models\\ it returns FruitTypes\Apples as expected. I know the backslash is an escape character, but doubling should treat those as actual backslashes.
If you want to use native functionality for this rather than string manipulation, then ReflectionClass::getShortName will do the job:
$reflection = new ReflectionClass('App\\Models\\FruitTypes\\Apple');
echo $reflection->getShortName();
Apple
See https://3v4l.org/eVl9v
preg_match() with the regex pattern \\([[:alpha:]]*)$ should do the trick.
$trimmed = preg_match('/\\([[:alpha:]]*)$/', $fruitName);
Your result will then live in `$trimmed1'. If you don't mind the pattern being a bit less explicit, you could do:
preg_match('/([[:alpha:]]*)$/', $fruitName, $trimmed);
And your result would then be in $trimmed[0].
If matches is provided, then it is filled with the results of search. $matches[0] will contain the text that matched the full pattern, $matches[1] will have the text that matched the first captured parenthesized subpattern, and so on.
preg_match - php.net
(matches is the third parameter that I named $trimmed, see documentation for full explanation)
An explanation for the regex pattern
\\ matches the character \ literally to establish the start of the match.
The parentheses () create a capturing group to return the match or a substring of the match.
In the capturing group ([[:alpha:]]*):
[:alpha:] matches a alphabetic character [a-zA-Z]
The * quantifier means match between zero and unlimited times, as many times as possible
Then $ asserts position at the end of the string.
So basically, "Find the last \ then return all letter between this and the end of the string".

PHP RegEx get first letter after set of characters

I have some text with heading string and set of letters.
I need to get first one-digit number after set of string characters.
Example text:
ABC105001
ABC205001
ABC305001
ABCD105001
ABCD205001
ABCD305001
My RegEx:
^(\D*)(\d{1})(?=\d*$)
Link: http://www.regexr.com/390gv
As you cans see, RegEx works ok, but it captures first groups in results also. I need to get only this integer and when I try to put ?= in first group like this: ^(?=\D*)(\d{1})(?=\d*$) , Regex doesn't work.
Any ideas?
Thanks in advance.
(?=..) is a lookahead that means followed by and checks the string on the right of the current position.
(?<=...) is a lookbehind that means preceded by and checks the string on the left of the current position.
What is interesting with these two features, is the fact that contents matched inside them are not parts of the whole match result. The only problem is that a lookbehind can't match variable length content.
A way to avoid the problem is to use the \K feature that remove all on the left from match result:
^[A-Z]+\K\d(?=\d*$)
You're trying to use a positive lookahead when really you want to use non-capturing groups.
The one match you want will work with this regex:
^(?:\D*\d{1})(\d*)$
The (?: string will start a non-capturing group. This will not come back in matches.
So, if you used preg_match(';^(?:\D*\d{1})(\d*)$;', $string, $matches) to find your match, $matches[1] would be the string for which you're looking. (This is because $matches[0] will always be the full match from preg_match.)
try:
^(?:\D*)(\d{1})(?=\d*$) // (?: is the beginning of a no capture group

Regex to match a specific expression format

I'm trying to find a regex that will match a specific expression in the following format:
name = value
However, I need it to not match:
name.extra = value
I have the following regex:
([\w\#\-]+) *(\=|\>|\>\=|\<|\<\=) *([^\s\']+)
which matches the first expression, but also matches the second expression (extra = value).
I need a regex that will match only the first expression and not the second (i.e. with a dot).
Just add ^ beginning and $ ending to your expression
^([\w\#\-]+) *(\=|\>|\>\=|\<|\<\=) *([^\s\']+)$
Negative lookbehind assertion (?<!) might be what you are looking for.
For a simple assignment: (?<!\.)\b(\w+)\s*=\s*(\w+)
summary:
(?<!\.) = prevent the character . at that location
\b = beginning of a word
The captured words are:
\1 = destination name
\2 = source name
and using the regex you specified, this should give something near this:
(?<!\.)\b([\w\#\-]+) *(\=|\>|\>\=|\<|\<\=) *([^\s\']+)
You don't say what language you're using, but it sounds like you don't need to use regexes at all.
If you're using PHP, then use the explode function to break apart on the =. Then check to see if the argument name has a period in it.

Categories