0

I want to get the input values in the string. I use two different patterns for this. But the result is the same. What is the reason of this?

$string = 'hello world is .. <input type="text" id="level" value="5">  <input type="text" id="option" value="24"> .. tyhis is example text.';

$pattern = '/<input(?:.*?)id=\"option\"(?:.*)value=\"([^"]+).*>/i';
$pattern2 = '/<input(?:.*?)id=\"level\"(?:.*)value=\"([^"]+).*>/i';

preg_match($pattern, $string, $matches);
preg_match($pattern2, $string, $matches2);
echo $matches[1];
echo "<br>";
echo $matches2[1];

Result:

24

24

What is the reason of this?

Community
  • 1
  • 1
J. Doe2
  • 1
  • 2
  • Because it's greedy. Why are you parsing html with regex? Add `?` after `.*` and you get this result: https://3v4l.org/L6n6I – Andreas Mar 30 '19 at 09:27
  • How greedy? Because, I need values inside the input. (?) – J. Doe2 Mar 30 '19 at 09:30
  • @Andreas If you want, you can answer with a post. I want accept. – J. Doe2 Mar 30 '19 at 09:51
  • Yes `.*` means match as much as possible (be greedy). Using `.*?` means match anything but stop as soon as possible (kind of). The answer to your question is not to add a `?` to the regex, it's to use a DOM parser. Parsing html with regex is not adviced. I will give you a link to a proper answer. – Andreas Mar 30 '19 at 10:05
  • See here: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 and here: https://stackoverflow.com/questions/3585087/regular-expression-regex-for-html-parsing-in-php – Andreas Mar 30 '19 at 10:07
  • Can you relocate the `class` and `value` elements, can you put the `value` element first? I tried, but I wasn't successful. this complicated for me @Andreas – J. Doe2 Mar 30 '19 at 10:36
  • not `class`; `id` – J. Doe2 Mar 30 '19 at 10:55
  • Yes you can **if you use a correct method**, regex is not the correct method. There are multiple reasons why regex is not the correct method, you found one, there are plenty more. Again use the correct tool, a DOM parser. – Andreas Mar 30 '19 at 11:17
  • Thank you for your time and help! @Andreas – J. Doe2 Mar 30 '19 at 12:19

1 Answers1

0

As @Andreas already stated your patterns contain greedy sections which swallow too much of the input. You need to reduce that:

<?php
$string = 'hello world is .. <input type="text" id="level" value="5">  <input type="text" id="option" value="24"> .. this is example text.';

$pattern1 = '/<input\s.*\sid=\"option\"\s.*?value=\"([^"]+).*>/i';
$pattern2 = '/<input\s.*\sid=\"level\"\s.*?value=\"([^"]+).*>/i';


preg_match($pattern1, $string, $matches1);
preg_match($pattern2, $string, $matches2);

var_dump($matches1[1], $matches2[1]);

The obvious output is:

string(2) "24"
string(1) "5"
arkascha
  • 41,620
  • 7
  • 58
  • 90