Помогите парсинг строки в PHP - PullRequest
2 голосов
/ 29 июня 2010

У меня будет такая строка:

Bob is a boy. Bob is 1000 years old! <b>Bob loves you!</b> Do you love bob?

Я хочу разобрать его в массив, используя следующие разделители для идентификации каждого элемента массива:

.
!
?
<b> and </b>

Итак, у меня будет массив со следующей структурой:

[0]Bob is a boy.
[1]Bob is 1000 years old!
[2]Bob loves you!
[3]Do you love bob?

Есть идеи?

Как видите, я бы хотел, чтобы текст от <b> до </b> был извлечен, ранее я использовал для этого следующее регулярное выражение:

preg_match_all(":<b>(.*?)</b>:is", $text, $matches);

Ответы [ 3 ]

2 голосов
/ 29 июня 2010

Я думаю, что это должно завершить то, что вы собираетесь:

$string = 'Bob is a boy. Bob is 1000 years old! <b>Bob loves you!</b> Do you love bob?'; 

// parser
$array = preg_split('/[\.|\!\?]|[\s]*<b>|<\/b>[\s]*/', $string, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE);
foreach ($array as $key => $element) $array[$key] = trim($element[0]).substr($string,$element[1]+strlen($element[0]),1);

print_r($array);

Это дает:

Array
(
    [0] => Bob is a boy.
    [2] => Bob is 1000 years old!
    [4] => Bob loves you!
    [6] => Do you love bob?
)

Первая строка анализатора захватывает каждую из строк текста междуразделители и их смещения в строке.Вторая строка добавляет знаки препинания из исходной строки в конец каждого элемента.

1 голос
/ 29 июня 2010

Разделяй и властвуй?

предположим, что $ myString - ваша строка ...

Сначала возьмите цитируемый материал:

preg_match (" /(.*?)<b>(.*?)<\/b>(.*?)/", $myString);

теперь у вас есть 1, 2 и 3 $ 100 *

$firstMatches = preg_split("/[\.\!\?]/", $1);

$lastMatches = preg_split("/[\.\!\?]/", $3);

Тогда верните пунктуацию:

function addPunctuation($matches, $myString)
{
    $punctuadedResults = array();
    foreach($matches as $match)
    {
       $position = strpos( $myString, $match);
       #position is the offset of the start of your match. Find the character after your match.
       $punctMark = substr($myString, $position + length($match), 1);
       $punctuadedResults[] = $match . $punctMark;

    }
    return $punctuadedResults;
}


$allMatches = addPunctuation($firstMatches, $myString);
$allMatches[] = $2;

$allMatches = array_merge($allMatches, addPunctuation($lastMatches, $myString) );
1 голос
/ 29 июня 2010

Если никто не предлагает лучшего решения, это почти работает:

(?:<b>|[.!?]*)((?:[^<]+?)(?:[.!?]+|</b>))\s+

Только он вернет Bob loves you!</b> в третьем матче, который можно очистить, применив strip_tags() к результатам, я думаю ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...