-12

I have string like this:

The time is over. # its mean I'm need to die. Please help me. # Ghost. I am here alone. Sorry. # help yourself.

I want to get the text between every # and dot (.) so I use this:

function get_string_between($string, $start, $end){
    $string = ' ' . $string;
    $ini = strpos($string, $start);
    if ($ini == 0) return '';
    $ini += strlen($start);
    $len = strpos($string, $end, $ini) - $ini;
    return substr($string, $ini, $len);
}

$parsed = trim(get_string_between($url, '#', '.'));
echo $parsed;

The problem its that the function return only the first example match to my query. I dont have any idea to do its for every query like I choose.

in this example string its need to return this:

its mean I'm need to die

Ghost

help yourself

Edit for @Nick Answer

My real string is this:

Text Text Text # Very good. #:* after this come example. Text Text Text #Very good number 2.

Your code also return me the string after #:*, I need only what seems like these examples: # Text Text. or #Text Text.

in the given example I need to get this texts:

Very good and Very good number 2

Ben
  • 9
  • 8
  • 2
    Your problem description is really unclear. Between every `#` and `.`? That means your matches in your first example string would be `(space)` and `its mean I'm need to die` is that correct? – Xatenev Dec 11 '18 at 09:54
  • 1
    Do you want the second result to be " Ghost" or " Ghost. I am here alone"? Because even with a loop of your function through the text, you'll still have an issue where the desired text has periods inside of it. Maybe the better aproach is finding the text between `#` and a linebreak? – Jared C Dec 11 '18 at 09:55
  • no, I just edit now the question to make it clear. @Xatenev see edit – Ben Dec 11 '18 at 09:55
  • @JaredC no because the query text can be in the middle of text. – Ben Dec 11 '18 at 09:57
  • 3
    So you copied the answer [here](https://stackoverflow.com/questions/5696412/how-to-get-a-substring-between-two-strings-in-php) without trying anything yourself and asked help from people? I call this being lazy. – Alexandre Elshobokshy Dec 11 '18 at 10:01

2 Answers2

4

Update

Based on OPs edit, the regex needs to be changed to use a positive lookahead for either a space or an alphabetic character immediately after the # i.e.

/#(?=[ A-Za-z])\s*([^.]*)\./

To use the text from the edit:

$string = "Text Text Text # Very good. #:* after this come example. Text Text Text #Very good number 2.";
preg_match_all('/#(?=[ A-Za-z])\s*([^.]*)\./', $string, $matches);
print_r($matches[1]);

Output

Array
(
    [0] => Very good
    [1] => Very good number 2
)

Updated demo on rextester

Original Answer

You can use preg_match_all to get the results you want. This regex looks for a set of characters between a # and a ., stripping any whitespace on either end by using a non-greedy capturing group and \s* on either side of the capturing group:

$string = "The time is over. # its mean I'm need to die .
Please help me. # Ghost. I am here alone.
Sorry. # help yourself.";
preg_match_all('/#\s*([^.]*?)\s*\./', $string, $matches);
print_r($matches[1]);

Output:

Array
(
    [0] => its mean I'm need to die
    [1] => Ghost
    [2] => help yourself
)

Demo on rextester

Nick
  • 138,499
  • 22
  • 57
  • 95
0

A combination of explode, substr, and strpos can do it:

Split the string by #, then get the string between # and the first . by using substr and strpos.

<?php

$examples = [
    'The time is over. # its mean I\'m need to die.',
'Please help me. # Ghost. I am here alone.',
'Sorry. # help yourself.'];

foreach($examples as $example) {
    $exploded = explode('#', $example);
    $substr = trim(substr($exploded[1], 0, strpos($exploded[1], '.')));
    var_dump($substr);
}

In a function for one specific string:

$test = parseString('Sorry. # help yourself.');
function parseString($string) {
    $exploded = explode('#', $string);
    $substr = trim(substr($exploded[1], 0, strpos($exploded[1], '.')));

    return $substr;
}

var_dump($test);

With string input we have to do an additional step that is breaking by \n before:

$stringExample = "The time is over. # its mean I'm need to die.
Please help me. # Ghost. I am here alone.
Sorry. # help yourself.";


$test2 = parseString2($stringExample);
function parseString2($string) {
    $result = [];
    $array = explode("\n", $string);

    foreach($array as $a) {
        $exploded = explode('#', $a);
        $substr = trim(substr($exploded[1], 0, strpos($exploded[1], '.')));    
        $result[] = $substr;
    }

    return $result;
}
var_dump($test2);

For string input without linebreaks, a little parser could look like:

$stringExample2 = "The time is over. # its mean I'm need to die. Please help me. # Ghost. I am here alone. Sorry. # help yourself.";


var_dump(parseString3($stringExample2));
function parseString3($stringExample)
{
    $result2 = [];

    $startBlock = false;

    $block = 0;
    foreach (str_split($stringExample) as $char) {
        if ($char === '#') { // Start block
            $startBlock = true;
        } else if ($startBlock && $char === '.') { // End block
            $result2[$block] = trim($result2[$block]); // Remove unnecessary whitespace
            $block++;
            $startBlock = false;
        } else if ($startBlock) { // Character to append to block
            if (!isset($result2[$block])) { // We have to check if the block has been started already and if not, create it as an empty string because otherwise we would get a notice when trying to append our character to it.
                $result2[$block] = '';
            }
            $result2[$block] .= $char;
        }

    }
    return $result2;
}

If you use any of this code, please make sure to actually understand what is happening and use adequate variable names, these are just small example snippets.

All examples with their output can be found in the 3v4l link below

https://3v4l.org/k3TXM

Xatenev
  • 6,383
  • 3
  • 18
  • 42