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