PHP's preg_match() returns (.*?) value only - php

I am struggling to get preg_match to return only the image URL and not the entire matched string. Do I need to use preg_replace after or is that getting hacky?
Possibly, would a different syntax get me what I need?
$source = file_get_contents('http://mysite.co.uk');
preg_match_all("'<div id=\"my-div\"><img src=\"(.*?)\" /></div>'", $source, $match);
echo $match[0][0];

If you use echo $match[0][0] you will have all the text.
<div id="my-div"><img src="blabla bla" /></div>
If you write $match[1][0] instead, you will get your subpattern match:
blabla bla

If you're looking for the first instance, you don't need to use preg_match_all():
$source = file_get_contents('http://mysite.co.uk');
if (preg_match('#<div id="my-div"><img src="(.*?)" /></div>#', $source, $match)) {
echo $match[1];
} else {
// no match found
}
Note that this regex will not match across multiple lines.
If you need all matches, then you were on the right track, but you were using index 0 instead of 1, so:
preg_match_all(..., $match);
foreach ($match as $m) {
echo $m[1]; // Use 1 here instead of 0; 1 is the first capture group, where 0 is the entire matched string
}

By default, preg_match_all always returns the fully matched string as the first item (using the ordering type PREG_PATTERN_ORDER).
From the documentation for PREG_PATTERN_ORDER:
Orders results so that $matches[0] is an array of full pattern
matches, $matches[1] is an array of strings matched by the first
parenthesized subpattern, and so on.
If you're looking for the value of a capturing group, check for a value at index 1 and then use the capturing group reference as a subattribute.
E.g., capturing group 1 would be: $matches[1][0]
To change this behavior you can pass a constant to as the third argument, such as PREG_SET_ORDER, which "Orders results so that $matches[0] is an array of first set of matches, $matches[1] is an array of second set of matches, and so on."

Related

Regular Expression For Time string [duplicate]

I need to print all matches using preg_match_all.
$search = preg_match_all($pattern, $string, $matches);
foreach ($matches as $match) {
echo $match[0];
echo $match[1];
echo $match[...];
}
The problem is I don't know how many matches there in my string, and even if I knew and if it was 1000 that would be pretty dumb to type all those $match[]'s.
The $match[0], $match[1], etc., items are not the individual matches, they're the "captures".
Regardless of how many matches there are, the number of entries in $matches is constant, because it's based on what you're searching for, not the results. There's always at least one entry, plus one more for each pair of capturing parentheses in the search pattern.
For example, if you do:
$matches = array();
$search = preg_match_all("/\D+(\d+)/", "a1b12c123", $matches);
print_r($matches);
Matches will have only two items, even though three matches were found. $matches[0] will be an array containing "a1", "b12" and "c123" (the entire match for each item) and $matches[1] will contain only the first capture for each item, i.e., "1", "12" and "123".
I think what you want is something more like:
foreach ($matches[1] as $match) {
echo $match;
}
Which will print out the first capture expression from each matched string.
Does print_r($matches) give you what you want?
You could loop recursively. This example requires SPL and PHP 5.1+ via RecursiveArrayIterator:
foreach( new RecursiveArrayIterator( $matches ) as $match )
print $match;

preg_match how to return matches?

According to PHP manual "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."
How can I return a value from a string with only knowing the first few characters?
The string is dynamic and will always change whats inside, but the first four character will always be the same.
For example how could I return "Car" from this string "TmpsCar". The string will always have "Tmps" followed by something else.
From what I understand I can return using something like this
preg_match('/(Tmps+)/', $fieldName, $matches);
echo($matches[1]);
Should return "Car".
Your regex is flawed. Use this:
preg_match('/^Tmps(.+)$/', $fieldName, $matches);
echo($matches[1]);
$matches = []; // Initialize the matches array first
if (preg_match('/^Tmps(.+)/', $fieldName, $matches)) {
// if the regex matched the input string, echo the first captured group
echo($matches[1]);
}
Note that this task could easily be accomplished without regex at all (with better performance): See startsWith() and endsWith() functions in PHP.
"The string will always have "Tmps" followed by something else."
You don't need a regular expression, in that case.
$result = substr($fieldName, 4);
If the first four characters are always the same, just take the portion of the string after that.
An alternative way is using the explode function
$fieldName= "TmpsCar";
$matches = explode("Tmps", $fieldName);
if(isset($matches[1])){
echo $matches[1]; // return "Car"
}
Given that the text you are looking in, contains more than just a string, starting with Tmps, you might look for the \w+ pattern, which matches any "word" char.
This would result in such an regular expression:
/Tmps(\w+)/
and altogether in php
$text = "This TmpsCars is a test";
if (preg_match('/Tmps(\w+)/', $text, $m)) {
echo "Found:" . $m[1]; // this would return Cars
}

php get grouped values in Regex

i am using php Regular expressions but i can't retrieve values that i group using ()
this is my input
<img src="http://www.example.com/image.jpg" title="title" />
i need only src value , this is my regex '"<img src=\"(.*?)\".*?\/>"'
if i can retrieve First group just like java patterns my problem is sloved
preg_match_all('"<img src=\"(.*?)\".*?\/>"', $source, $re);
print_r($re);
and it return full image tag like this <img src="http://www.example.com/image.jpg" title="title" />
To match a single string, preg_match function is enough. You don't need to go for preg_matchall function. If you want to match more number of strings then you could use preg_matchall function. And also first try to match the exact string through the pattern rather than to go for grouping. If it's impossible to match a particular string then go for grouping.
In the below, matching the exact value of src attribute is done.
You could get the value of src in two ways,
1. positive lookbehind
Regex:
(?<=src=\")[^\"]*
PHP code:(Through match_all)
<?php
$string = "<img src=\"http://www.example.com/image.jpg\" title=\"title\" />";
$regex = '~(?<=src=\")[^\"]*~';
preg_match_all($regex, $string, $matches);
print_r($matches);
?>
PHP code:(Through match)
<?php
$string = "<img src=\"http://www.example.com/image.jpg\" title=\"title\" />";
$regex = '~(?<=src=\")[^\"]*~';
if (preg_match($regex, $string, $m)) {
$yourmatch = $m[0];
echo $yourmatch;
}
?> //=> http://www.example.com/image.jpg
Explanation:
(?<=src=\") Positive look-behind is used here. So the regex engine puts the match marker just after to the src=".
[^\"]* Now it starts matching any character zero or more times but not of ". When it finds a ", it stops matching characters.
2. Using \K
Regex:
src=\"\K[^\"]*
PHP code (through match)
<?php
$string = "<img src=\"http://www.example.com/image.jpg\" title=\"title\" />";
$regex = '~src=\"\K[^\"]*~';
if (preg_match($regex, $string, $m)) {
$yourmatch = $m[0];
echo $yourmatch;
}
?> //=> http://www.example.com/image.jpg
Explanation:
\K resets the starting point of the reported match. Any previously consumed characters are no longer included in the final match.
src=\"\K So it discards the previously matched src=".
[^\"]* Matches any character zero or more times but not of "
You're using preg_match_all so that you need to pass index as well, use print_r($re[1]); to get results.
I Got It Accidently !
we can Code Like this for first Grouped
print_r($re[1]);

preg matching and replacing elements

Hi how do I do a preg match on
$string1 = "[%refund%]processed_by"
$string2 = "[%refund%]date_sent"
I want to grab the bits inside %% and then remove the [%item%] altogether. leaving just the "proccessed_by" or "date_sent" I have had a go below but come a bit stuck.
$unprocessedString = "[%refund%]date_sent"
$match = preg_match('/^\[.+\]/', $unprocessedString);
$string = preg_replace('/^\[.+\]/', $unprocessedString);
echo $match; // this should output refund
echo $string; // this should output date_sent
Your problem is with your use of the preg_match function. It returns the number of matches found. But if you pass it a variable as a third parameter, it stores the matches for the entire pattern and its subpatterns in an array.
So you can capture both of the parts you want in subpatterns with preg_match, which means you don't need preg_replace:
$unprocessedString = "[%refund%]date_sent"
preg_match('/^\[%(.+)%\](.+)/', $unprocessedString, $matches);
echo $matches[1]; // outputs 'refund'
echo $matches[2]; // outputs 'date_sent'

preg_match_all print *all* matches

I need to print all matches using preg_match_all.
$search = preg_match_all($pattern, $string, $matches);
foreach ($matches as $match) {
echo $match[0];
echo $match[1];
echo $match[...];
}
The problem is I don't know how many matches there in my string, and even if I knew and if it was 1000 that would be pretty dumb to type all those $match[]'s.
The $match[0], $match[1], etc., items are not the individual matches, they're the "captures".
Regardless of how many matches there are, the number of entries in $matches is constant, because it's based on what you're searching for, not the results. There's always at least one entry, plus one more for each pair of capturing parentheses in the search pattern.
For example, if you do:
$matches = array();
$search = preg_match_all("/\D+(\d+)/", "a1b12c123", $matches);
print_r($matches);
Matches will have only two items, even though three matches were found. $matches[0] will be an array containing "a1", "b12" and "c123" (the entire match for each item) and $matches[1] will contain only the first capture for each item, i.e., "1", "12" and "123".
I think what you want is something more like:
foreach ($matches[1] as $match) {
echo $match;
}
Which will print out the first capture expression from each matched string.
Does print_r($matches) give you what you want?
You could loop recursively. This example requires SPL and PHP 5.1+ via RecursiveArrayIterator:
foreach( new RecursiveArrayIterator( $matches ) as $match )
print $match;

Categories