在列位置拆分字符串

Split string at column positions

我正在使用

ps -l -u user

获取给定用户的 运行 个进程。

现在,当我想将信息拆分为 PHP 中的数组时,我遇到了麻烦,因为 ps 输出数据供人类阅读,没有固定的分隔符。所以你不能用 space 或制表符作为正则表达式拆分。

到目前为止,我只能按字符位置检测列。

php有什么方法可以在特定位置将字符串拆分为数组吗?类似于:

$array=split_columns($string, $positions=array(1, 10, 14))

要在位置 1、10 和 14 处将字符串切成几段?

在PHPpreg_split这里会帮助到你。您可以按多个空格分隔,例如:

<?
$text = '501   309     1     4004   0   4  0  2480080  10092 -      S                   0 ??         0:36.77 /usr/sbin/cfpref
  501   310     1 40004004   0  37  0  2498132  33588 -      S                   0 ??         0:23.86 /usr/libexec/Use
  501   312     1     4004   0  37  0  2471032   8008 -      S                   0 ??        19:06.48 /usr/sbin/distno';
$split = preg_split ( '/\s+/', $text);
print_r($split);

如果您知道列数,则可以遍历数组并将该列数作为一行。

我决定尝试使用动态模式构建的正则表达式方法。不确定这是最好的方法,但你可以试试看:

function split_columns ($string, $indices) {
    $pat =  "";
    foreach ($indices as $key => $id) {
        if ($key==0) { 
            $pat .= "(.{" . $id . "})";
        } else if ($key<count($indices)) {
            $pat .= "(.{" . ($id-$indices[$key-1]) . "})";
        }
    }
    $pats = '~^'.$pat.'(.*)$~m';
    preg_match_all($pats, $string, $arr);
    return array_slice($arr, 1);
}
$string = "11234567891234567\n11234567891234567"; // 1: '1', 2: '123456789', 3: '1234', 4: '567'
print_r (split_columns($string, $positions=array(1, 10, 14)));

PHP demo

重点是:

  • 动态构建模式,方法是检查索引,从每个后续索引值中减去先前的索引值,并在末尾附加 (.*)$ 以匹配该行的其余部分。
  • m 修饰符是 ^ 匹配行首和 $ 行尾所必需的。
  • array_slice($arr, 1); 将从结果数组中删除完全匹配项。
  • 示例正则表达式(满足 OP 要求))看起来像 ^(.{1})(.{9})(.{4})(.*)$

我修改了 Wiktor 的解决方案,因为我不需要那么多信息。

function split_columns ($string, $indices) {
    $pat =  "";
    foreach ($indices as $key => $id) {
        if ($key==0) { 
            $pat .= "(.{" . $id . "})";
        } else if ($key<count($indices)) {
            $pat .= "(.{" . ($id-$indices[$key-1]) . "})";
        }
    }
    $pats = '~^'.$pat.'(.*)$~m';
    preg_match_all($pats, $string, $arr, PREG_SET_ORDER);
    $arr=$arr[0];
    return array_slice($arr, 1);
}