查找并返回数组中找到的字符串

时间:2011-06-01 20:05:15

标签: php arrays

我正在寻找适合以下情况的功能。

脚本的作用: 它从一个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

3 个答案:

答案 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]
  }
}