使用php分割大段不同类型数据为相同类型的字符串集合
对于
要求分割时间,呼吸率,心率,距离。
想法如下:
利用fseek,fread和fgets的组合,以读取第二列呼吸率为例。发现第一列宽度大多为7,随后有一个空格,然后到了第二列,第二列长度大多为7.
实践如下:
fseek('$file',8,SEEK_CUR) //使得文件指针偏移到我们要读取的第二列数据开头
fread('$file',7) //读取第二列7个字符
fgets('$file') //这一步仅仅是为了使文件指针进入下一行
以上写一个for循环就能够读取所有第二列数据。
问题如下:
Q:(1)有一个很明显的问题就是我们不知道有多少行数据,所以不知道要循环多少次
A:(1)使用$arr=file('文件路径');会返回文件结果为数组,每一行为数组的一个元素,再使用count($arr);就可以获得数组长度。
Q:(2)刚才说到第一列大部分宽度为7,如果我们按照上述方式每次偏移8位,每次读取7个字符,就会导致当宽度不为7时(比如31行),读取会出现错误,结果
是0.971 。不仅少读还会多两个空格。
A:(2)这个问题我一开始想分类讨论,第一列长度为6的我们偏移7个读7个,第一列长度为7的我们偏移8个读7个,这似乎又出来的问题,如果第二列只有6个字符的
情况呢(比如31行)。所以这种方法也行不通,或者想要实现还需要进一步分类讨论,太过繁琐。
A:(2)好在php中自带的explode函数拯救了我,不仅能实现上述需求,还能更进一步将四类数据有序分类。代码如图:
fgets读取一行,观察到虽然每列数据长度不一,但是中间都是用制表符\t分隔的,所以我们用explode函数将其分割为数组,结果保存在res,其中res数组下标的0,1,2,3分别
对应着时间,呼吸率,心率,距离;下次需要使用哪个数据作图或者分析都会方便很多。
以上
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
我有点较真,用了长长的分隔符来写下面的文章。
上面是使用函数来实现分割的,能不能用自己的代码来实现呢。仅举分割一行的例子。
题目:$str="12 13 14";要求分割出12,13,14,并且储存在字符串数组中。
我的想法:
既然数字之间使用数量不一的空格分隔的(制表符的外在表示也是空格),那么就以空格作为分割依据,具体做法如下:
(1)遍历字符串,找出空格的下标并用pos数组记录他们的位置
这里看到的5,6,7,8就是制表符占的4个空格
(2)接下来用for循环来还原字符串,其中需要做到两点:(I)算清每个字符串的起始位置,(II)计算出字符串长度
针对(I),我们发现分别是从0,$pos[1],和end($pos)开始的(对于中间连续空格,我们可做判断,如果$pos[i]-$pos[i-1]==1就continue)
针对(II),第一个字符串长度就是第一个空格出现的数组元素的值,即$pos[0],第二个字符串长度就是$pos[i]-$pos[i-1],第三个字符串长度很显然就是
strlen($str)-end($pos)。
如此,便可解决问题。
ps:(1)对于确定了起始位置和长度后,我们是一个一个将字符写进字符串里,并且我们希望最后的结果能保留在一个字符串数组中,即有一个字符串数组$string,
$string[0]=12,$string[0]=13,$string[0]=14。
(2)要想实现需要创建一个过渡字符串string_tmp,每读到一个数字$string[i].=$string_tmp;('.'的作用是连接两个字符串)
这里有两个问题需要注意:(I)切不可以直接$string[i].=$string_tmp,举个例子就懂了
这个结果会是多少呢。
大家稍微看一下就懂了,我就不赘述。
要想达到上面的目的,让他成为一个字符串数字怎么办呢,我的方法是:
结果如下:
实现功能!如果数组下标超过1行不行呢?答案是可以的。我的理解是你给他引好了路,他就会一直按照这条路走,如果不引,就是默认的路。
(II)可以使用trim函数调整表达形式,去除前后端的空格。
下面是我的代码:
1 <?php 2 $test_str="12 13 14"; 3 $j=0; 4 for($i=0;$i<strlen($test_str);$i++){ 5 //echo "strcmp($test_str[$i], ' ')"; 6 if(strcmp($test_str[$i], " ")==0){ 7 //echo "strcmp($test_str[$i], ' ')"; 8 $pos[$j]=$i; 9 $j++; 10 } 11 } 12 //断点位置为pos,断点个数为j, 13 //echo "断点有{$j}个"; 14 //var_dump(strlen($test_str)); 15 var_dump($pos); 16 $string=array( 17 0=>"", 18 1=>"" 19 ); 20 $k=0; 21 for($i=0;$i<$j;$i++){ 22 if($i==0){ 23 $len=$pos[$i]; 24 }else{ 25 $len=$pos[$i]-$pos[$i-1]; 26 } 27 if($len==1)continue; 28 $string_tmp=""; 29 for($m=0;$m<$len;$m++){ 30 if($i==0){ 31 $string_tmp.=$test_str[$m]; 32 }else{ 33 $string_tmp.=$test_str[$m+$pos[$i-1]]; 34 } 35 } 36 //echo "$string_tmp "; 37 $string[$k]=trim($string_tmp); 38 $k++; 39 } 40 $string_tmp=""; 41 for($m=0;$m<strlen($test_str)-end($pos);$m++){ 42 $string_tmp.=$test_str[$m+end($pos)]; 43 }$string[$k]=trim($string_tmp); 44 //var_dump(end($pos)); 45 var_dump($string); 46 47 ?>