私はこのコードをテストしていませんが、私はこの正規表現以外の考え方がうまくいくと思います。基本的には、文字列をスペースで分割し、各部分を解析します。このアプローチでは、部品の順序は関係ありません。
コンテンツとプロジェクトが複数の部分にまたがる可能性があるので少し難しいですが、私のコードでそれを処理する必要があります。また、1つのハットタグ、ユーザー、プロジェクト、およびツイートごとの優先度しか持たないことを前提としています。たとえば、複数のハッシュタグがある場合は、文字列ではなく配列に入れてください。最後に、奇妙なことが起きないようにするためのエラー処理はありません。
は、ここに私のテストされていないコードです:私はあなたが使用して、あなたの正規表現に誤りがあると思う
$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);
「\ w」とは何と思いますか? '[a-zA-Z]'とほぼ同じです – Vyktor
マッチをループして、#、@、!で始まらないすべてのマッチから文字列を構成してください。 &[ – Yaniro