Я не тестировал этот код, но я думаю, что эта идея без регулярных выражений может работать лучше для вас.По сути, вы разбиваете строку на пробелы, а затем анализируете каждый фрагмент.Этот подход означает, что не имеет значения, в каком порядке детали.
Это немного сложно, потому что контент и проект могут состоять из нескольких частей, но я думаю, что мой код должен с этим справитьсяТакже предполагается, что у вас есть только один хэштег, пользователь, проект и приоритет на твит.Например, если будет несколько хэштегов, просто поместите их в массив вместо строки.Наконец, он не обрабатывает ошибки, чтобы обнаружить / предотвратить странные вещи.
Вот мой непроверенный код:
$data = array(
'hash' => '',
'user' => '',
'priority' => '',
'project' => '',
'content' => ''
);
$parsingProjectName = false;
foreach(explode(' ', $tweet) as $piece)
{
switch(substr($piece, 0, 1))
{
case '#':
$data['hash'] = substr($piece, 1);
break;
case '@':
$data['user'] = substr($piece, 1);
break;
case '!':
$data['priority'] = substr($piece, 1);
break;
case '[':
// Check if the project name is longer than 1 word
if(strpos($piece, -1) == ']')
{
$data['project'] = substr($piece, 1, -1);
}
else
{
// There will be more to parse in the next piece(s)
$parsingProjectName = true;
$data['project'] = substr($piece, 1) . ' ';
}
break;
default:
if($parsingProjectName)
{
// Are we at the end yet?
if(strpos($piece, -1) == ']')
{
// Yes we are
$data['project'] .= substr($piece, 1, -1);
$parsingProjectName = false;
}
else
{
// Nope, there is more
$data['project'] .= substr($piece, 1) . ' ';
}
}
else
{
// We aren't in the middle of parsing the project name, and this piece doesn't start with one of the special chars, so assume it is content
$data['content'] .= $piece . ' ';
}
}
}
// There will be an extra space on the end; remove it
$data['content'] = substr($data['content'], 0, -1);