Получить весь текст вне скобок при захвате индекса слова - PullRequest
0 голосов
/ 05 мая 2018

Как я могу получить весь текст, который не в скобках, используя preg_match_all? Причина, по которой мне нужно использовать preg_match_all, заключается в том, что я хочу получить индекс каждого слова.

Данное предложение:

Здравствуйте, как поживаете, сэр?

Я могу извлечь все слова внутри ( ), который работает. Как я могу также получить весь текст вне ( ) отдельно?

preg_match_all('/\[t-(.*?)\]/', $this->target, $targetWords, PREG_OFFSET_CAPTURE);

Выход:

Array
(
    [0] => Array
        (
            [0] =>  are
            [1] => 47
        ),
    [0] => Array
        (
            [0] =>  today
            [1] => some number
        )

)

Примечание : Я уже знаю о preg_split:

$outsideParenthesis = preg_split('/\[.*?\]/', $this->target);

Но это не позволяет мне поддерживать индекс.


Примечание 2: Может помочь в достижении моей конечной цели:

Я хочу взять строку пользовательской уценки. Для каждого слова я хочу генерировать объекты слова, которые определяют их тип и содержание.

Причина в том, что я хотел бы отправить массив объектов Word для внешнего интерфейса, чтобы я мог циклически проходить по массиву и генерировать HTML-элементы с классами, чтобы при необходимости применять стилизацию.

И я хочу иметь возможность указать любую уценку в пределах, например,

Здравствуйте, как поживаете, сэр?

Где t- это цель, k- это ключ.

Итак, окончательный массив, который я хотел бы, выглядел бы так:

[
   [
      type => 'normal'
      content => 'Hello how '
   ],
   [
      type => 'target'
      content => 'are'
   ],
   [
      type => 'normal'
      content => ' you'
   ]
   [
      type => 'key'
      content => 'today'
   ]
   [
      type => 'normal'
      content => ', Sir?'
   ]
]

Вот моя функция wordObjects:

private function setWordObjects($array, $type)
{
    return array_map(function ($n) use ($type) {
        return [
            'type' => $type,
            'content' => $n[0],
            'index' => $n[1]
        ];
    }, $array[1]);
}

Ответы [ 2 ]

0 голосов
/ 05 мая 2018

С preg_match_all

$str = 'Hello how [t- are] you [k- today], Sir?';

$types = ['' => 'normal', 't' => 'target', 'k' => 'key'];

if ( preg_match_all('~ (?| \[ (?<type>[^]-]+) - \h (?<content>[^]]+) ]
                         | () ([^[]+) ) ~x', $str, $matches, PREG_SET_ORDER) ) {
    foreach ($matches as &$m) {
        unset($m[0], $m[1], $m[2]);
        $m['type'] = $types[$m['type']];
    }
    print_r($matches);
}

демо

0 голосов
/ 05 мая 2018

Расширенное решение:

$s = 'Hello how [t- are] you [k- today], Sir?';
$types = ['t-' => 'target', 'k-' => 'key'];
$splitted = preg_split('/\[([tk]- [^]]+)\]/', $s, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_OFFSET_CAPTURE);

$result = [];
foreach ($splitted as $v) {
    [$content, $pos] = $v;
    $k = substr($content, 0, 2);
    $is_delim = isset($types[$k]);
    $result[] = array_combine(['type', 'content', 'index'],
                              [$is_delim? $types[$k] : 'normal',
                              $is_delim? substr($content, 3) : $content,
                              $is_delim? $pos + 3 : $pos]);
}

print_r($result);

Выход:

Array
(
    [0] => Array
        (
            [type] => normal
            [content] => Hello how 
            [index] => 0
        )

    [1] => Array
        (
            [type] => target
            [content] => are
            [index] => 14
        )

    [2] => Array
        (
            [type] => normal
            [content] =>  you 
            [index] => 18
        )

    [3] => Array
        (
            [type] => key
            [content] => today
            [index] => 27
        )

    [4] => Array
        (
            [type] => normal
            [content] => , Sir?
            [index] => 33
        )
)
...