Tutorial :How can I match everything in a string until the second occurrence of a delimiter with a regular expression?



Question:

I am trying to refine a preg_match_all by finding the second occurrence of a period then a space:

<?php    $str = "East Winds 20 knots. Gusts to 25 knots. Waters a moderate chop.  Slight chance of showers.";    preg_match_all ('/(^)((.|\n)+?)(\.\s{2})/',$str, $matches);    $dataarray=$matches[2];  foreach ($dataarray as $value)  { echo $value; }  ?>  

But it does not work: the {2} occurrence is incorrect.

I have to use preg_match_all because I am scraping dynamic HTML.

I want to capture this from the string:

East Winds 20 knots. Gusts to 25 knots.  


Solution:1

Here is a different approach

$str = "East Winds 20 knots. Gusts to 25 knots. Waters a moderate chop.  Slight chance of showers.";      $sentences = preg_split('/\.\s/', $str);    $firstTwoSentences = $sentences[0] . '. ' . $sentences[1] . '.';      echo $firstTwoSentences; // East Winds 20 knots. Gusts to 25 knots.  


Solution:2

Why not just get all periods then a space and only use some of the results?

preg_match_all('!\. !', $str, $matches);  echo $matches[0][1]; // second match  

I'm not sure what exactly you want to capture from this however. Your question is a little vague.

Now if you want to capture everything up to and including the second period (followed by a space) try:

preg_match_all('!^((?:.*?\. ){2})!s', $str, $matches);  

It uses a non-greedy wildcard match and DOTALL so . matches newlines.

If you don't want to capture the last space, you can do that too:

preg_match_all('!^((?:.*?\.(?= )){2})!s', $str, $matches);  

Also you may want to allow the string termination to count, which means either:

preg_match_all('!^((?:.*?\.(?: |\z)){2})!s', $str, $matches);  

or

preg_match_all('!^((?:.*?\.(?= |\z)){2})!s', $str, $matches);  

Lastly, since you're after one match and want the first one, you could just as easily use preg_match() rather than preg_match_all() for this.


Solution:3

I don't think (.\s{2}) means what you think it means. As it stands, it will match ". " (a period followed by two spaces), not the second occurence of ". "


Solution:4

You can try:

<?php  $str = "East Winds 20 knots. Gusts to 25 knots. Waters a moderate chop.  Slight chance of showers.";  if(preg_match_all ('/(.*?\. .*?\. )/',$str, $matches))      $dataarrray = $matches[1];  var_dump($dataarrray);  ?>  

Output:

array(1) {    [0]=>    string(40) "East Winds 20 knots. Gusts to 25 knots. "  }  

Also if you want to capture just one occurrence, why are you using preg_match_all ? preg_match should suffice.


Solution:5

no need regex. think simple

$str = "East Winds 20 knots. Gusts to 25 knots. Waters a moderate chop.  Slight chance of showers.";  $s = explode(". ",$str);  $s = implode(". ",array_slice($s,0,2)) ;  print_r($s);  


Solution:6

I want to capture this from the string: East Winds 20 knots. Gusts to 25 knots.

I have two suggestions:

1) Simply Explode the string at ". " (double space) and just print the result.

$arr = explode(".  ",$str);  echo $arr[0] . ".";  // Output: East Winds 20 knots. Gusts to 25 knots.  

2) Use Explode and Strpos which is more performance-friendly than Preg_match_all.

foreach( explode(".",$str) as $key=>$val) {      echo (strpos($val,"knots")>0) ? trim($val) . ". " : "";  }  // Output: East Winds 20 knots. Gusts to 25 knots.  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »