我正在寻找适合以下情况的功能。
脚本的作用: 它从一个minecraft服务器检索server.log,并将其分为用户聊天,服务器通知等部分。
我有一个包含用户信息的数组,它由另一个名为users.yml的文件设置 并将其转换为类似的数组
$userconfig = array(
'TruDan' => array(
'prefix' => '&3',
'suffix' => '&e',
),
'TruGaming' => array(
'prefix' => '&c',
'suffix' => '&f',
),
'PancakeMiner' => array(
'prefix' => '&c',
'suffix' => '&f',
),
'Teddybear952' => array(
'prefix' => '&b',
'suffix' => '&f',
),
);
我想要做的是从server.log(它通过行循环)搜索$ line以获取上面的用户名(数组键)并返回数组。所以我可以解析$ ret ['prefix']和$ ret ['suffix']
mc.php(文件)http://pastebin.com/9geyfuup server.log(部分,实际的东西是12,000行,所以我从它那里拿了几行)http://pastebin.com/DKz8YfgK
答案 0 :(得分:1)
如果您使用preg_match()搜索每一行的用户名,请确保首先使用rsort()
以相反的顺序对用户名列表进行排序:
$users = array_map('preg_quote', array_keys($userconfig));
rsort($users);
$pattern = '/' . implode('|', $users); . '/';
if preg_match($pattern, $line, $matches) {
return matches[0];
}
else {
return array();
}
如果您在一行中搜索模式"/TruDan|TruDan123/"
,则搜索会将包含"TruDan123"
的行与较短版本"TruDan"
匹配,因为它是在模式中首先指定的。以相反的顺序对用户列表进行排序可确保模式为"/TruDan123|TruDan/"
,因此优先考虑较长的匹配。
答案 1 :(得分:0)
所以你想要'TruDan','TruGaming','PancakeMiner'和'Teddybear952',看看它们是否出现在特定的日志文件中?
$names = array_keys($userconfig); // get the user names
$name_regex = implode('|', $names); // produce a|b|c|d
... load your log file
foreach($lines as $line) {
if (preg_match("/($names)/", $line, $matches)) { // search for /(a|b|c|d)/ in the string
echo "found $matches[1] in $line";
print_r($userconfig[$matches[1]]); // show the user's config data.
}
}
当然,这很简单。如果用户名中有任何正则表达式元字符,它将导致正则表达式中出现语法错误,因此您需要在构建正则表达式子句之前按一下名称。
答案 2 :(得分:0)
我不确定我是否100%理解这个问题,但根据我收集的内容,你想使用上面的数组(键)作为针,而$line
作为大海捞针?
可以通过多种方式实现,但是:
// Regex Method
// this depends on how big this array is though, however, otherwise this
// regex pattern could potentially be HUGE.
$pattern = sprintf('/(%s)/g', implode('|', array_map('preg_quote',array_keys($userconfig))));
if (preg_match($pattern,$line,$matches)){
// $matches has all names found in the line
// $userconfig[$match[1]]
}
否则你可以继续迭代键:
// "brute fore"
// this keeps checking for $name int he $line over and over, but no real
// optimizations going on here.
foreach (array_keys($userconfig) as $name)
{
if (strpos($line,$name) !== false)
{
// $name was found in $line
// $userconfig[$name]
}
}