4

This is my string

#Jhon: Manager #Mac: Project Manager #Az: Owner

And I want array something like this

$array = ['0' => 'Manager', '1' => 'Project Manager', '2' => 'Owner']

I tried this but each time return only 'Manager'

$string = '#Jhon: Manager #Mac: Project Manager #Az: Owner';
getText($string, ':', ' #')
public function getText($string, $start, $end)
{
  $pattern = sprintf(
      '/%s(.+?)%s/ims',
      preg_quote($start, '/'), preg_quote($end, '/')
  );

  if (preg_match($pattern, $string, $matches)) {
      list(, $match) = $matches;
      echo $match;
  }
} 
Komal
  • 2,716
  • 3
  • 24
  • 32
  • Try using `preg_match_all`. But remeber, owner doesn't have the end character `#`. So only `Manager` and `Project Manager` will be matched – Thamilhan May 05 '17 at 11:37
  • Functionally related: [preg match to get text after @ symbol and before next space using php](https://stackoverflow.com/q/25914018/2943403) – mickmackusa May 18 '23 at 13:27
  • Related: [preg_match_all get text between 2 strings](https://stackoverflow.com/q/6976707/2943403) and [Get string between every two certain characters with PHP](https://stackoverflow.com/q/53721443/2943403) – mickmackusa May 18 '23 at 13:59

4 Answers4

8

You may preg_split the contents and use the following solution:

$re = '/\s*#[^:]+:\s*/';
$str = '#Jhon: Manager #Mac: Project Manager #Az: Owner';
$res = preg_split($re, $str, -1, PREG_SPLIT_NO_EMPTY);
print_r($res);

See the PHP demo and a regex demo.

Pattern details:

  • \s* - 0+ whitespaces
  • # - a literal # symbol
  • [^:]+ to match 1+ chars other than :
  • : - a colon
  • \s* - 0+ whitespaces.

Note that -1 in the preg_split function is the $limit argument telling PHP to split any amount of times (as necessary) and PREG_SPLIT_NO_EMPTY will discard all empty matches (this one may be removed if you need to keep empty matches, that depends on what you need to do further).

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • Thanks wiktor.. but when my string is '#Jhon: Manager #Mac@gmail.com: Project Manager #Az: Owner' not working.. sorry for not specify this possibility – Komal May 05 '17 at 12:12
  • @Komal: But I already wrote - use `[^:\s]+` in that case, use [`\s*#[^:\s]+:\s*`](https://regex101.com/r/P0s10e/2). I removed the `\w`-based regex variation. – Wiktor Stribiżew May 05 '17 at 12:14
  • One more possibility is space between name '#Jhon M: Manager #Mac@gmail.com: Project Manager #Az: Owner' – Komal May 05 '17 at 13:37
  • @Komal: Then how can you differentiate `#` as the starting point of the key and a `#` that is part of the value? – Wiktor Stribiżew May 05 '17 at 13:40
  • Ok, remove `\s` from the `[^:\s]+`. See [**this demo**](https://regex101.com/r/P0s10e/3). – Wiktor Stribiżew May 05 '17 at 13:46
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/143507/discussion-between-komal-and-wiktor-stribizew). – Komal May 05 '17 at 13:48
6

Here we are using preg_match to achieve desired output.

Regex: #\w+\s*\:\s*\K[\w\s]+

1. #\w+\s*\:\s*\K this will match # then words then spaces and then : \K will reset current match.

2. [\w\s]+ This will match your desired output which contains words and spaces.

Solution 1:

<?php
ini_set('display_errors', 1);
$string="#Jhon: Manager #Mac: Project Manager #Az: Owner";
preg_match_all("/#\w+\s*\:\s*\K[\w\s]+/", $string,$matches);
print_r($matches);

Output:

Array
(
    [0] => Array
        (
            [0] => Manager 
            [1] => Project Manager 
            [2] => Owner
        )

)


Here we are using array_map and explode to achieve desired out. Here we first we are exploding string on # and then exploding its array values on : and pushing its first index in the resultant array.

Solution 2:

Try this code snippet here

<?php

$string="#Jhon: Manager #Mac: Project Manager #Az: Owner";
$result=  array_map(function($value){
    return trim(explode(":",$value)[1]);
}, array_filter(explode("#", $string)));
print_r(array_filter($result));

Output:

Array
(
    [1] => Manager
    [2] => Project Manager
    [3] => Owner
)
Sahil Gulati
  • 15,028
  • 4
  • 24
  • 42
  • @SahilGulati 2nd Gives me error Undefined offset: 1, and first is working but not worked when my string is '#Jhon: Manager #Mac@gmail.com: Project Manager #Az: Owner' sorry for not specifing this possibility.. – Komal May 05 '17 at 12:10
  • @Komal Hope this will help you out.. I have updated my post for that for demo you can check this https://eval.in/787827 – Sahil Gulati May 05 '17 at 12:31
  • 1
    This way is indeed better since the pattern starts with a literal character. You can remove the eventual trailing spaces using: https://regex101.com/r/tgjssx/1 – Casimir et Hippolyte May 05 '17 at 19:52
  • @Casimir just for my safe side i added this so that OP will not face any further issues with other string input which may contain spaces.. Anyways thanks sir...:) – Sahil Gulati May 05 '17 at 19:55
0

You can use explode() function to split the string by char. After that just replace the elements of new array with preg_replace().

radoAngelov
  • 684
  • 5
  • 12
0

Try this

$string = '#Jhon: Manager #Mac: Project Manager #Az: Owner';
$res = explode("#", $string);
$result = array();
for($i = 1; $i < count($res); $i++)  {
    $result[] = preg_replace("/(^[A-Z][a-z]*: )/", "", $res[$i]);
}