Extract multiple Strings between two String in PHP - php

I am trying to make this work but I can't:
$str = "<html>1</html><html>2</html><html>3</html>";
$matches = array();
preg_match_all("(?<=<html>)(.*?)(?=</html>)", $str, $matches);
foreach ($matches as $d)
{
echo $d;
}
What I am doing wrong? The output must be:
123

This should work for you:
$str = "<html>1</html><html>2</html><html>3</html>";
preg_match_all("~(?<=<html>).*?(?=</html>)~", $str, $matches);
foreach ($matches[0] as $d) {
echo $d;
}
Output:
123
Changes are:
Use missing regex delimiters ~ in preg_match_all function pattern
Remove capturing group since you are already using lookahead and lookbehind so entire match can be used in further processing
Using $matches[0] in foreach loop instead of $matches
There is no need to declare/initialize $matches before preg_match_all call

You need to add delimiters (I've used !) and you can skip the lookaheads/lookbehinds. Just make a capture group around the numbers you want. Nothing else.
Then look in the second matches element for the array with the individual values.
Example:
preg_match_all("!<html>(.*?)</html>!", $str, $matches);
foreach ($matches[1] as $d)
{
echo $d;
}

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;

How do I get number from this format:,[[5,["95",1,"#ffffff"]]]], using regex

I have a string like this:
",[[3,"bus.png",null,"Bus",[["https://maps.gstatic.com/mapfiles/transit/iw2/b/bus.png",0,[15,15],null,0]]]],[[null,null,null,null,"0x31da18325b415901:0xeb661015c651c24a",[[5,["48",1,"#ffffff"]]]],[null,null,null,null,"0x31da19f34e04d59b:0x5758ef6990938b",[[5,["61",1,"#ffffff"]]]],[null,null,null,null,"0x31da1a5b8b75c379:0x6a13e189555f9fab",[[5,["95",1,"#ffffff"]]]],[null,null,null,null,"0x31da1a16ea23bf95:0xd7c90f15535c2b9f",[[5,["106",1,"#ffffff"]]]],[null,null,null,null,"0x31da10a7613d616f:0xf1f61ffeac2ea8a4",[[5,["970",1,"#ffffff"]]]],[null,null,null,null,"0x31da1a0bd6262d0b:0xfbd5d2bfd7a1252",[[5,["NR8",1,"#ffffff"]]]]],null,0,"5"]]],["http://www
I need to get all the numbers: "48, 61,95,106,970,NR8"; so basically, need to process this format :"48, 61,95,106,970,NR8"
I tried:
function get_numbers_from($input) {
$matches = preg_match_all('(\[\"[]a-zA-Z0-9]*?\"\,\d*?\,\".*?\"\])', $input);
foreach($matches[1] as $key => $match) {
array_push($numbers, explode(',', $match)[0]);
}
return $numbers;
}
But seems it shows: Invalid argument supplied for foreach()
How to correct it?
Check the manual for preg_match_all(), the function returns a boolean. And you use the third parameter for the matches.
Also you can change your regex to this one:
\[\[\d+,\[\"(\w+)\",\d+,"#[\da-fA-F]+"]]]]
To get the number directly from it without explode(), e.g.
function get_numbers_from($input) {
preg_match_all('/\[\[\d+,\[\"(\w+)\",\d+,"#[\da-fA-F]+"]]]]/', $input, $matches);
return $matches[1];
}
You can use
'~\["([A-Z]*\d+)"~'
See the regex demo and the IDEONE demo
$re = '~\["([A-Z]*\d+)"~';
$str = "\",[[3,\"bus.png\",null,\"Bus\",[[\"https://maps.gstatic.com/mapfiles/transit/iw2/b/bus.png\",0,[15,15],null,0]]]],[[null,null,null,null,\"0x31da18325b415901:0xeb661015c651c24a\",[[5,[\"48\",1,\"#ffffff\"]]]],[null,null,null,null,\"0x31da19f34e04d59b:0x5758ef6990938b\",[[5,[\"61\",1,\"#ffffff\"]]]],[null,null,null,null,\"0x31da1a5b8b75c379:0x6a13e189555f9fab\",[[5,[\"95\",1,\"#ffffff\"]]]],[null,null,null,null,\"0x31da1a16ea23bf95:0xd7c90f15535c2b9f\",[[5,[\"106\",1,\"#ffffff\"]]]],[null,null,null,null,\"0x31da10a7613d616f:0xf1f61ffeac2ea8a4\",[[5,[\"970\",1,\"#ffffff\"]]]],[null,null,null,null,\"0x31da1a0bd6262d0b:0xfbd5d2bfd7a1252\",[[5,[\"NR8\",1,\"#ffffff\"]]]]],null,0,\"5\"]]],[\"http://www\n48, 61,95,106,970,NR8";
preg_match_all($re, $str, $matches);
print_r($matches[1]);
The pattern matches:
\[ - a [
" - a quote
([A-Z]*\d+) - Group 1: any uppercase ASCII letter, 0 or more times, followed with 1 or more digits
" - a quote
The value you need is located inside the $matches[1] variable. It holds all the values captured with the parenthesized subpattern (Group 1).

Regular expression for between two dynamic patterns

I want to find anything that matches
[^1] and [/^1]
Eg if the subject is like this
sometext[^1]abcdef[/^1]somemoretext[^2]12345[/^2]
I want to get back an array with abcdef and 12345 as the elements.
I read this
And I wrote this code and I am unable to advance past searching between []
<?php
$test = '[12345]';
getnumberfromstring($test);
function getnumberfromstring($text)
{
$pattern= '~(?<=\[)(.*?)(?=\])~';
$matches= array();
preg_match($pattern, $text, $matches);
var_dump($matches);
}
?>
Your test checks the string '[12345]' which does not apply for the rule of having an "opening" of [^digit] and a "closing" of [\^digit]. Also, you're using preg_match when you should be using: preg_match_all
Try this:
<?php
$test = 'sometext[^1]abcdef[/^1]somemoretext[^2]12345[/^2]';
getnumberfromstring($test);
function getnumberfromstring($text)
{
$pattern= '/(?<=\[\^\d\])(.*?)(?=\[\/\^\d\])/';
$matches= array();
preg_match_all($pattern, $text, $matches);
var_dump($matches);
}
?>
That other answer doesn't really apply to your case; your delimiters are more complex and you have to use part of the opening delimiter to match the closing one. Also, unless the numbers inside the tags are limited to one digit, you can't use a lookbehind to match the first one. You have to match the tags in the normal way and use a capturing group to extract the content. (Which is how I would have done it anyway. Lookbehind should never be the first tool you reach for.)
'~\[\^(\d+)\](.*?)\[/\^\1\]~'
The number from the opening delimiter is captured in the first group and the backreference \1 matches the same number, thus insuring that the delimiters are correctly paired. The text between the delimiters is captured in group #2.
I have tested following code in php 5.4.5:
<?php
$foo = 'sometext[^1]abcdef[/^1]somemoretext[^2]12345[/^2]';
function getnumberfromstring($text)
{
$matches= array();
# match [^1]...[/^1], [^2]...[/^2]
preg_match_all('/\[\^(\d+)\]([^\[\]]+)\[\/\^\1\]/', $text, $matches, PREG_SET_ORDER);
for($i = 0; $i < count($matches); ++$i)
printf("%s\n", $matches[$i][2]);
}
getnumberfromstring($foo);
?>
output:
abcdef
123456

String Manipulation in PHP

I've got a string in php it can be in one of two formats - either:
"example1" AND somethingelse = "example2"
or just
"example1"
All I need is to get the data in the speechmarks, whether both or just the one.
Cheers!
preg_match( '/"([^"]*)"/' , $string, $matches )
# $matches is an array with the results
# ignore $matches[0]
# $matches[1] will contain the first string inside double-quotes
# $matches[2] will contain the second string inside double-quotes (if any)
more info here: http://www.php.net/manual/en/function.preg-match.php
If you are looking to replace text, following a certain regex would help:
http://php.net/manual/en/function.preg-replace.php
OR, if you're not wanting to replace text, you can match it using:
http://www.php.net/manual/en/function.preg-match.php
Thanks for the help, I managed it in a slightly backwards way, using the basis of bowsersenior's answer and some simple counting!
//Find amount of Speech marks
$stringCount = substr_count($newstring, '"');
if ($stringCount == 2){
preg_match( '/".*?"/' , $newstring, $matches);
foreach ($matches as $data)
{
print_r($data);
}
}else{
//Get first speech marks
preg_match( '/".*?"/' , $newstring, $matches);
foreach ($matches as $data)
{
print_r($data);
}
//Get second speech marks
$endString = substr($newstring,-4);
echo $endString;
}

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