在列位置拆分字符串
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)));
重点是:
- 动态构建模式,方法是检查索引,从每个后续索引值中减去先前的索引值,并在末尾附加
(.*)$
以匹配该行的其余部分。
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);
}
我正在使用
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)));
重点是:
- 动态构建模式,方法是检查索引,从每个后续索引值中减去先前的索引值,并在末尾附加
(.*)$
以匹配该行的其余部分。 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);
}