在列位置处分割字符串

3

我正在使用

ps -l -u user

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

现在,当我想在 PHP 中将信息拆分成数组时,我遇到了麻烦,因为 ps 输出数据供人类阅读,没有固定的分隔符。因此,您无法使用空格或制表符作为正则表达式进行拆分。

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

在 PHP 中是否有一种将字符串拆分为特定位置的数组的方法?类似于:

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

将字符串在位置1、10和14处分割成多个片段?

preg_match_all('^(.)(.{10})(.{4})m', $s, $matches)? - Wiktor Stribiżew
awk在这里很有用。 - LF00
我们这里没有 [mcve]。 - mickmackusa
3个回答

1
我决定尝试使用动态模式构建的正则表达式方法。不确定这是否是最佳方法,但你可以尝试一下:
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演示

要点如下:

  • 通过检查索引、从每个后续索引值中减去前一个索引值,并在末尾添加(.*)$来动态构建模式以匹配其余行。
  • m修饰符对于使^匹配行的开头和$匹配行的结尾是必需的。
  • array_slice($arr, 1);将从结果数组中删除完整匹配。
  • 满足OP要求的示例正则表达式将类似于^(.{1})(.{9})(.{4})(.*)$

太棒了。我稍微修改一下以适应我的需求。我不需要多维数组。 - Juergen Schulze

1

我修改了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);
}

0
在PHP中,preg_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);

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

1
我已经尝试过了 - 当然。问题在于,使用空格分割时,ps命令无法给出一致的结果。你可能会得到12个数组元素和下一行15个元素。例如,这取决于ps中列出的命令是否包含空格。 - Juergen Schulze
1
然后,您可以使用此处的答案:https://dev59.com/cnA75IYBdhLWcg3wxcHV#11071688,并创建适合您需求的格式。 - Martin Cup
我会看一下的。谢谢。 - Juergen Schulze

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接