Consider :
$array=array();
$string = "an url link: url('example.com/abc'),another url link :url('example1.com/foo=bar')";
if (preg_match("regex expression of url('')")
array_push("the whole url string start from 'url(' then end with ')'");
Suppose I have the code above , how to write the above statement in the correct way ?
http://www.phpliveregex.com/p/fE0
preg_match_all("/url\(\'(.*?)\'\)/", $inputSTR, $output);
preg_match_all will match all parts of the string that meet the criteria.
\( and\' means escape regex and make it literal. In short, make sure the ( is a ( and not a part of the regex pattern.
(.*?) match anything and be lazy. This means to only match till first time the regex is no longer matched.
\'\) the end of the search pattern
Related
I'm writing a simple quiz engine in PHP and supply the question text in this format
question|correct/feedback|wrong/feedback|wrong/feedback
There can be as many wrong/feedback options as necessary. I want to use preg_match to return the results so I can display them. For instance:
q|aaa/aaa|bbb/bbb|ccc/ccc
...should return...
array(
0 => q|aaa/aaa|bbb/bbb|ccc/ccc
1 => q
2 => aaa/aaa
3 => bbb/bbb
4 => ccc/ccc
)
So, far I've got this regular expression which matches the question and the correct/feedback combination...
([^\|]+)\|([^\/]+\/[^\|$]+)
...but I have no idea how to match the remaining wrong/feedback strings
You can also use the "glue" feature in your pattern with preg_match_all, this way it's possible to check if the syntax is correct and to extract each part at the same time.
The glue feature ensures that each match follows immediately the previous match without gap. To do that I use the A global modifier (Anchored to the start of the string or the next position after the previous match).
$s = 'q|aaa/aaa|bbb/bbb|ccc/ccc';
$pat = '~ (?!\A) \| \K [^|/]+ / [^|/]+ (?: \z (*:END) )? | \A [^|/]+ ~Ax';
if ( preg_match_all($pat, $s, $m) && isset($m['MARK']) ) {
$result = $m[0];
print_r($result);
}
I use also a marker (*:END) to be sure that the end of the string is well reached despite of the pattern constraints. If this marker exists in the matches array, it's a proof that the syntax is correct. Advantage: you have to parse the string only once (you don't even need to check the whole string syntax in a lookahead assertion anchored at the start of the string).
demo
If you want the whole question as first item in the result array, just write:
$result = array_merge([$s], $m[0]);
So, after the advice, I've decided to use preg_match to check the syntax and then explode to split the string.
This regex seems to match the string format up until any mismatch occurs.
^[^\|/]+(?:\|[^\|/]+/[^\|/]+)+
If I check that the length of the match is the same as the original string I think this will tell me the syntax is correct. Does this sound feasible?
i want to preg_match following as it is
$this_string = '{95}1340{113}1488{116}1545{99}1364';
My best try was
preg_match('/^[\{\d+\}\d+]+$/', $this_string);
That matches
{95}1340{113}1488
but also
{95}1340{113}
which is wrong.
I know why it is matching last example. One match {95}1340 was true, so '+' 'll be always true. But i don't know how to tell, if it match, so it has always be a complete match in '[…]'
i do expect only matches likes these
{…}…
{…}…{…}…
{…}…{…}…{…}…
one of the tries:
^(\{\d+\}\d+)+$
does also match
{99}1364
at the very last end of this string as a second match, so i get back an Array with two Elements:
Array[0] = {95}1340{113}1488{116}1545{99}1364 and
Array[1] = {99}1364
Problem is unnecessary use of character class in your regex i.e. [ and ].
You can use:
'/^(\{\d+\}\d+)+$/'
The translation of your regex to a clearer thing would be: /^[\{\}0-9+]+$/, this would be explained as everything that is inside this chracters {}0123456789+, exactly those ones.
What you want is grouping, for grouping, parentheses are needed and not character classes () instead [], so what you want to do is replace [] for ().
Short answer: '/^(\{\d+\}\d+)+$/'
What you are trying to do is a little unclear. Since your last edit, I assume that you want to check the global format of the string and to extract all items (i.e. {121}1231) one by one. To do that you can use this code:
$str = '{95}1340{113}1488{116}1545{99}1364';
$pattern = '~\G(?:{\d+}\d+|\z)~';
if (preg_match_all($pattern, $str, $matches) && empty(array_pop($matches[0])))
print_r($matches[0]);
\G is an anchor for the start of the string or the end of the previous match
\z is an anchor for the end of the string
The alternation with \z is only needed to check that the last match is at the end of the string. If the last match is empty, you are sure that the format is correct until the end.
I've been stuck with a fairly simple preg_match for a while and was wondering if someone could help me out.
Here is what im trying to do.
$string = 'Sub Total£24.00Shipping£5.95Grand Total£29.95Email:';
$m = preg_match('/Shipping(.*?)\Grand/s', $string, $match);
the array $match is returning empty and I really cant understand why.
The \G token is the "last match" position anchor (like in PERL).
You need to esacape it:
\\G
More info:
The anchor \G matches at the position where the previous match ended. During the first match attempt, \G matches at the start of the string in the way \A does.
Source: http://regular-expressions.mobi/continue.html
It looks like you shouldn't have the \ before Grand. The sequence \G must mean something.
I got the following URL
http://www.amazon.com/LEGO-Ultimate-Building-Set-Pieces/dp/B000NO9GT4/ref=sr_1_1?m=ATVPDKIKX0DER&s=toys-and-games&ie=UTF8&qid=1350518571&sr=1-1&keywords=lego
and I want to extract
B000NO9GT4
that is the asin...to now, I can get search between the string, but not in this way I require. I saw the split functin, I saw the explode. but cant find a way out...also, the urls will be different in length so I cant hardcode the length two..the only thing which make some sense in my mind is to split the string so that
http://www.amazon.com/LEGO-Ultimate-Building-Set-Pieces/dp/
become first part
and
B000NO9GT4/ref=sr_1_1?m=ATVPDKIKX0DER&s=toys-and-games&ie=UTF8&qid=1350518571&sr=1-1&keywords=lego
becomes the 2nd part , from the second part , I should extract B000NO9GT4
in the same way, i would want to get product name LEGO-Ultimate-Building-Set-Pieces from the first part
I am very bad at regex and cant find a way out..
can somebody guide me how I can do it in php?
thanks
This grabs both pieces of information that you are looking to capture:
$url = 'http://www.amazon.com/LEGO-Ultimate-Building-Set-Pieces/dp/B000NO9GT4/ref=sr_1_1?m=ATVPDKIKX0DER&s=toys-and-games&ie=UTF8&qid=1350518571&sr=1-1&keywords=lego';
$path = parse_url($url, PHP_URL_PATH);
if (preg_match('#^/([^/]+)/dp/([^/]+)/#i', $path, $matches)) {
echo "Description = {$matches[1]}<br />"
."ASIN = {$matches[2]}<br />";
}
Output:
Description = LEGO-Ultimate-Building-Set-Pieces
ASIN = B000NO9GT4
Short Explanation:
Any expressions enclosed in ( ) will be saved as a capture group. This is how we get at the data in $matches[1] and $matches[2].
The expression ([^/]+) says to match all characters EXCEPT / so in effect it captures everything in the URL between the two / separators. I use this pattern twice. The [ ] actually defines the character class which was /, the ^ in this case negates it so instead of matching / it matches everything BUT /. Another example is [a-f0-9] which would say to match the characters a,b,c,d,e,f and the numbers 0,1,2,3,4,5,6,7,8,9. [^a-f0-9] would be the opposite.
# is used as the delimiter for the expression
^ following the delimiter means match from the beginning of the string.
See www.regular-expressions.info and PCRE Pattern Syntax for more info on how regexps work.
You can try
$str = "http://www.amazon.com/LEGO-Ultimate-Building-Set-Pieces/dp/B000NO9GT4/ref=sr_1_1?m=ATVPDKIKX0DER&s=toys-and-games&ie=UTF8&qid=1350518571&sr=1-1&keywords=lego" ;
list(,$desc,,$num,) = explode("/",parse_url($str,PHP_URL_PATH));
var_dump($desc,$num);
Output
string 'LEGO-Ultimate-Building-Set-Pieces' (length=33)
string 'B000NO9GT4' (length=10)
I want to find the first matching string in a very very long text. I know I can use preg_grep() and take the first element of the returned array. But it is not efficient to do it like that if I only need the first match (or I know there is exactly only one match in advance). Any suggestion?
preg_match() ?
preg_match() returns the number of
times pattern matches. That will be
either 0 times (no match) or 1 time
because preg_match() will stop
searching after the first match.
preg_match_all() on the contrary will
continue until it reaches the end of
subject. preg_match() returns FALSE if
an error occurred.
Here's an example of how you can do it:
$string = 'A01B1/00asdqwe';
$pattern = '~^[A-Z][0-9][0-9][A-Z][0-9]+~';
if (preg_match($pattern, $string, $match) ) {
echo "We have matched: $match[0]\n";
} else {
echo "Not matched\n";
}
You can try print_r($match) to check the array structure and test your regex.
Side note on regex:
The tilde ~ in the regex are just delimiters needed to wrap around
the pattern.
The caret ^ denote that we are matching from the start
of the string (optional)
The plus + denotes that we can have one or
more integers that follow. (So that A01B1, A01B12, A01B123 will also
be matched.