我正在分析一条推文,将其作为向数据库添加提醒的快速方法。推特看起来像这样:
$tweet = '#notes @username !high_priority [Project Name] Tweet content';
我使用下面的正则表达式来获取#,@!和[项目]
$match = preg_match_all('/(#''w*[a-zA-Z_]+''w*)|(!''w*[a-zA-Z_]+''w*)|(@''w*[a-zA-Z_]+''w*)|(''[[^'']]*''])/i',
$tweet,
$matches);
我想知道如何获取剩余的"Tweet内容",这样所有与正则表达式不匹配的内容都应该保存到一个变量中。
此外,如果推特更像:,匹配顺序会重要吗
$tweet = '@username Tweet content [Project Name] #notes !high_priority';
有人知道怎么做吗?
将正则表达式匹配的文本替换为空字符串。剩下的是正则表达式不匹配的内容。
我还没有测试过这段代码,但我认为这种非正则表达式的想法可能更适合您。从本质上讲,您可以用空格分割字符串,然后解析每一部分。这种方法意味着零件的顺序无关紧要。
这有点棘手,因为内容和项目可以跨越多个部分,但我认为我的代码应该处理好这一点。它还假设每条推文只有一个标签、用户、项目和优先级。例如,如果有多个标签,只需将它们放在一个数组中,而不是字符串中。最后,它没有任何错误处理来检测/防止奇怪的事情发生。
这是我未经测试的代码:
$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);
使用preg_split
而不是preg_match_all
,然后获得介于两者之间的所有组件,作为Brent返回单个字符串的答案的替代方案。请注意,许多匹配项可能为空。
我认为在[a-zA-Z_]之前使用''w时,您的RegEx中出现了一个错误,看起来您想要匹配空白,而''w匹配单词字符。你可以这样做(对于这个小部分):
...''s*[''w_]+''s*...
由于您似乎已经在匹配中循环以获得不同的部分,因此可以为要匹配的纯文本创建一个子模式,或者将其与模式的其余部分连接。这样一来,你只需要再打一场比赛。只要在循环匹配的同时区分匹配的部分,这也适用于不同的内容顺序。