Extract URL parameters with regex - repeating a capture group - php

I'm attempting to extract the URL parameters via regex and am sooo close to getting it to work. I even know what the problem is: my regex is stumbling on repeated capture groups. But I simply cannot figure out how to fix it.
Language is PHP.
My URL looks something like the one below. It can have no parameters, just one or multiple:
member.php?action=bla&arg=2&test=15&schedule=16
My regex looks like this:
member\.php((?:[\?|&](\w*)=(\w*))*)
And my capture groups end up being:
1. action=bla&arg=2&test=15&schedule=16
2. schedule
3. 16
I cannot figure out how to capture all the parameters individually. Will I just have to settle for the first capture group and explode it myself? It would be much more elegant for my purposes if I can do all the work inside one regex.

try:
<?php
$str="member.php?action=bla&arg=2&test=15&schedule=16#test";
preg_match_all('/([^?&=#]+)=([^&#]*)/',$str,$m);
print_r($m);
//combine the keys and values onto an assoc array
$data=array_combine( $m[1], $m[2]);
print_r($data);
?>

Have you tried parse_url and parse_str ?

Extract parameters and their values with-> &[\w]*=[\d]*

Related

Get specific string content inside big string

I have a big string like this:
[/az_column_text][/vc_column_inner][vc_column_inner width="3/4"]
[az_latest_posts post_layout="listed-layout" post_columns_count="2clm" post_categories="assemblea-soci-2015"]
[/vc_column_inner][/vc_row_inner][/vc_column]
What I need to extract:
assemblea-soci-2015
Of course this value can change, and also the big string can change too. I need a regex or something else to extract this value (it will be always from post_categories="my-value-to-extract") from this big string.
I think to take post_categories=" as the beginning of a possible substring and the next char " as the end of my portion, but no idea how to do this.
Is there an elegant way to do this also for future values with, of course, different length?
You can use this regex in PHP:
post_categories="\K[^"]+
RegEx Demo
You can use this regex:
(?<=post_categories=")[^"]+(?=")
?<= (lookbehind) looks for post_categories=" before the desired match, and (?=) (lookahead) looks for " after the desired match.
[^"] gets the match (which is assumed not to contain any ")
Demo
Example PHP code:
$text='[/az_column_text][/vc_column_inner][vc_column_inner width="3/4"]
[az_latest_posts post_layout="listed-layout" post_columns_count="2clm" post_categories="assemblea-soci-2015"]
[/vc_column_inner][/vc_row_inner][/vc_column]';
preg_match ("/(?<=post_categories=\")[^\"]+(?=\")/", $text,$matches);
echo $matches[0];
Output:
assemblea-soci-2015
This should extract what you want.
preg_match ("/post_categories=\"(.*)\"\[\]/", $text_you_want_to_use)

Need a regular expression to capture url path

I am using PHP, and I have been trying to create a regular expression pattern to capture part of URL path, but to no avail.
The possible URL path could be any of these:
"product/zzz"
"yyyyyyyy/product/zzz"
"xxxxx/yyyyyyyy/product/zzz"
"xxxxx/yyyyyyyy/.../product/zzz" (... means other possible words)
what I need to capture is the part before "product".
for the first case, the result should be an empty string.
for the rest, they are "yyyyyyyy", "xxxxx/yyyyyyyy" and "xxxxx/yyyyyyyy/..."
Can anyone here give me hint? thanks!
PS.
It looks like the part I wanted is a repetition of same pattern "xxxx/". but I am not good at using group of regex.
Update:
I probably found a solution, by capturing pattern "xxx/" with zero or more repetitions: "([^/]+/)*"
so the full regex should be "(([^/]+/)*)product/([^/]+)"
#SERPRO: it passed the test in your "Live RegExp".
Hope it is helpful.
I would use parse_url():
$path = parse_url($url, PHP_URL_PATH);
// Deal with $path to figure out what's after '/product/'
This should work for you:
#(.*?)/?product.*\b#
You can see an example of result strings here:
http://xrg.es/#5awa10
This should do it:
^(.*[^/]|)/*product/[^/]+/*$
It will also allow an arbitrary number of slashes at the end of the path.
The part inside parentheses is your result.

str_replace two times

i have an question.
I have this code
<?php
echo str_replace("CDAS","","2/CDAS2/CDAS");
?>
that outputs
2/2/
How do i make it so it only delete "CDAS", like the "match whole word" option in Notepad?
Thanks!
Use a regular expression and specify word boundaries:
echo preg_replace('/\bCDAS\b/', '', '2/CDAS2/CDAS');
Here's a demo.
Use preg_replace:
preg_replace('/CDAS$/', '', "2/CDAS2/CDAS")
Something like that.
Of course since I actually have no idea what output you want I cannot be certain this is the right answer.
Not sure how to fully answer this as what you've described does what it does but I'm guessing you just want the second CDAS item removed?
There are so many ways to skin a cat but perhaps a flexible way would be to use the explode operator to separate the string into components with the '/' symbol and you can then use a while loop or otherwise to replace any matching CDAS items and exit when ever you want.
http://php.net/manual/en/function.explode.php
and finally recombine the compoents back into a string either with implode or just concatenate the array items.

Regular expression to extract from URI

I need a regular expression to extract from two types of URIs
http://example.com/path/to/page/?filter
http://example.com/path/to/?filter
Basically, in both cases I need to somehow isolate and return
/path/to
and
?filter
That is, both /path/to and filter is arbitrary. So I suppose I need 2 regular expressions for this? I am doing this in PHP but if someone could help me out with the regular expressions I can figure out the rest. Thanks for your time :)
EDIT: So just want to clearify, if for example
http://example.com/help/faq/?sort=latest
I want to get /help/faq and ?sort=latest
Another example
http://example.com/site/users/all/page/?filter=none&status=2
I want to get /site/users/all and ?filter=none&status=2. Note that I do not want to get the page!
Using parse_url might be easier and have fewer side-effects then regex:
$querystring = parse_url($url, PHP_URL_QUERY);
$path = parse_url($var, PHP_URL_PATH);
You could then use explode on the path to get the first two segments:
$segments = explode("/", $path);
Try this:
^http://[^/?#]+/([^/?#]+/[^/?#]+)[^?#]*\?([^#]*)
This will get you the first two URL path segments and query.
not tested but:
^https?://[^ /]+[^ ?]+.*
which should match http and https url with or without path, the second argument should match until the ? (from the ?filter for instance) and the .* any char except the \n.
Have you considered using explode() instead (http://nl2.php.net/manual/en/function.explode.php) ? The task seems simple enough for it. You would need 2 calls (one for the / and one for the ?) but it should be quite simple once you did that.

preg_match returning weird results

I am searching a string for urls...and my preg_match is giving me an incorrect amount of matches for my demo string.
String:
Hey there, come check out my site at www.example.com
Function:
preg_match("#(^|[\n ])([\w]+?://[\w]+[^ \"\n\r\t<]*)#ise", $string, $links);
echo count($links);
The result comes out as 3.
Can anybody help me solve this? I'm new to REGEX.
$links is the array of sub matches:
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.
The matches of the two groups plus the match of the full regular expression results in three array items.
Maybe you rather want all matches using preg_match_all.
If you use preg_match_pattern, (as Gumbo suggested), please note that if you run your regex against this string, it will both match the value of your anchor attribute "href" as well as the linked Text which in this case happens to comtain an url. This makes TWO matches.
It would be wise to run an array_unique on your resultset :)
In addition to the advice on how to use preg_match, I believe there is something seriously wrong with the regular expression you are using. You may want to trying something like this instead:
preg_match("_([a-zA-Z]+://)?([0-9a-zA-Z$-\_.+!*'(),]+\.)?([0-9a-zA-Z]+)+\.([a-zA-Z]+)_", $string, $links);
This should handle most cases (although it wouldn't work if there was a query string after the top-level domain). In the future, when writing regular expressions, I recommend the following web-sites to help: http://www.regular-expressions.info/ and especially http://regexpal.com/ for testing them as you're writing them.

Categories