请教一下各位关于字符串操作的问题~~(已解决)
本帖最后由 annybaby 于 2011-3-27 21:19 编辑有一个文本文件保存着如下内容
A1 4.5 8.9 90 ABCD
RSE2 5.62 2.77 0 CC
HS1 -1.98-2.57745 ABCD
C30058.75 5.7 180 ESD
上面的规律描述起来比较麻烦:
每一行分成五个部分(由空格或TAB键分开 第一部分和第五部分是一般字符串,中间的三部分是数,
长度可能不同,有正有负(如果处理有难度,可以当全部是正的)
我需要做的:
比较第五部分,如果是一样的话(比如上面的第一行和第三行,大家都是“ABCD”,那么需要记录下来,比如赋值给某个变量,然后将内容进行一些变换,再写到一个新建的文件里面去,比如说,上面的内容,我希望转换成下面这样的
A1 +004.500 +008.900 90 1 - ABCD
HS1 -001.980 -002.577 45 1 - ABCD
RSE2 +005.620 +002.770 0 2 - CC
C300 +008.750 +005.700 180 3 - ESD
上面转换后变成了七部分,第五部分中数字按自然数增加,表示种类,如果第七部分在前面已经出现过,则第五部分的数字与其一致,比如上面的:
第二行第七部分也是“ABCD”,与第一行的第七部分一样,所以对应的第五部分也与其一致,都是“1”
而第三行的"CC",由于前面没有出现过,所以对应的第五部分就按自然数增加1,变成“2”,第三行同样道理~~
拜托各位高手啦~~ 基本上是纯体力活,改数字格式比较麻烦…… 另,照现在的规律
C300 +008.750 +005.700 180 3 - ESD
应该是
C300 +058.750 +005.700 180 3 - ESD 回复 2# afan
对,不好意思,是我打错啦,{:face (113):} 基本上是纯体力活,改数字格式比较麻烦…… 另,照现在的规律
C300 +008.750 +005.700 180 ...
afan 发表于 2011-3-8 23:49 http://www.autoitx.com/images/common/back.gif
数字格式用stringformat()应该可以吧??
我最不会的是如何准确读取到里面的各个部分,正则表达式也不会用~~ 本帖最后由 www378660084 于 2011-3-9 00:17 编辑
输入text.txt (tab分割)
A1 4.5 8.9 90 ABCD
RSE2 5.62 2.77 0 CC
HS1 -1.98 -2.577 45 ABCD
C300 58.75 5.7 180 ESD
输出out.txt(在这显示有点问题)
A1 +004.500 +008.900 90 1 - ABCD
HS1 -001.980 -002.577 45 1 - ABCD
RSE2 +005.620 +002.770 0 2 - CC
C300 +058.750 +005.700 180 3 - ESD
#include <Array.au3>
Global $lineNum = 0
Global $lines
Global $sortIndex =
Global $lineArr
;读取文件
Global $filein = FileOpen("text.txt", 0)
Local $str
$str = FileReadLine($filein)
While $str <> ""
$lineNum += 1
$lines[$lineNum] = $str
$str = FileReadLine($filein)
WEnd
FileClose($filein)
Local $i, $j, $tmpArr
For $i = 1 To $lineNum
$tmpArr = StringSplit($lines[$i], " ")
;_ArrayDisplay($tmpArr)
For $j = 0 To 4
If $j = 1 Or $j = 2 Then
$lineArr[$i][$j] = format($tmpArr[$j + 1])
Else
$lineArr[$i][$j] = $tmpArr[$j + 1]
EndIf
Next
Next
;排列
Local $tmp
For $i = 1 To $lineNum
For $j = $i + 1 To $lineNum
If StringCompare($lineArr[$j], $lineArr[$i]) < 0 Then
$tmp = $sortIndex[$i]
$sortIndex[$i] = $sortIndex[$j]
$sortIndex[$j] = $tmp
EndIf
Next
Next
;写出
Global $fileout = FileOpen("out.txt", "2")
Local $num = 1
For $i = 1 To $lineNum
$str = $lineArr[$sortIndex[$i]]
If $i > 1 And $lineArr[$sortIndex[$i]] <> $lineArr[$sortIndex[$i - 1]] Then $num += 1
For $j = 1 To 3
$str = $str & " " & $lineArr[$sortIndex[$i]][$j]
Next
$str = $str & " " & $num & " " & "-" & " " & $lineArr[$sortIndex[$i]]
FileWriteLine($fileout, $str)
Next
Func format($str)
Local $ret = "", $tmp = ""
Local $num = Number($str)
Local $int = Int($num)
$num = Abs($num - $int)
$ret = StringFormat("%+04d", $int)
$tmp = StringFormat("%.3f", $num)
$tmp = StringReplace($tmp, "0.", ".")
$ret = $ret & $tmp
Return $ret
EndFunc ;==>format
回复 5# www378660084
谢谢先,不过我运行了下,输出如下
A1 +000.000 +000.000 1 -
RSE2 +000.000 +000.000 1 -
HS1 +000.000 +000.000 1 -
C300 +000.000 +000.000 1 -
即:可以是这样
A1 +004.500 +008.900 90 1 - ABCD
HS1 -001.980 -002.577 45 1 - ABCD
RSE2 +005.620 +002.770 0 2 - CC
C300 +058.750 +005.700 180 3 - ESD
也可以是这样:
A1 +004.500 +008.900 90 1 - ABCD
RSE2 +005.620 +002.770 0 2 - CC
C300 +058.750 +005.700 180 3 - ESD
HS1 -001.980 -002.577 45 1 - ABCD
另外,你程序里面的排列我看不懂{:face (394):}
我有这样的想法,但是不会用循环实现{:face (207):}
按您前面的方法,将内容保存到一个二维数组里面,比如$array存放着第一行,然后用数组的一个位置存放一个标志,比如$array[]初始化为0,从第二行开始,与之比较,相同的话,就用一个标志记录,比如输入中第三行也是"ABCD",就可以将$array改成1,依此类推,一直到尾,然后第二次从第二行开始,先判断是否与前一轮比较有相同的(看$array是否为1),如果是表明和第一行的是一样的,直接执行下一次循环,如果不同,表明是一个新元素,直接加1,即
$array=2,然后后面又逐行比较~~
我用for 循环搞了一下下午都没有成功~~ #include <Array.au3>
Local $avArray = [['A1', '4.5', '8.9', '90', 'ABCD'], ['RSE2', '5.62', '2.77', '0', 'CC'], ['HS1', '-1.98', '-2.577', '45', 'ABCD'], ['C300', '58.75', '5.7', '180', 'ESD']]
_ArrayDisplay($avArray, "默认排序方式" )
_ArraySort($avArray, 0, 0, 0, 0)
_ArrayDisplay($avArray, "副索引0升序排列方式" )
_ArraySort($avArray, 0, 0, 0, 1)
_ArrayDisplay($avArray, "副索引1升序排列方式" )
_ArraySort($avArray, 0, 0, 0, 2)
_ArrayDisplay($avArray, "副索引2升序排列方式" )
..... #include <array.au3>
#include <file.au3>
local $array
_FileReadToArray("bb.txt",$array)
local $out_array,$k=1,$str
for $i=1 to $array
$temp=StringSplit(StringStripWS($array[$i],4),chr(32),2)
$temp=_format($temp)
$temp=_format($temp)
for $n=0 to 3
$out_array[$i][$n]=$temp[$n]
Next
$out_array[$i]='-'
$out_array[$i]=$temp
if not IsDeclared($temp) then
Assign($temp,$k)
$k+=1
EndIf
Next
;_ArraySort($out_array,0,0,0,6);如果需要排序
for $i=1 to $array
if IsDeclared($out_array[$i]) then $out_array[$i]=Eval($out_array[$i])
Next
_ArrayDisplay($out_array)
for $i=1 to UBound($out_array)-1
for $n=0 to UBound($out_array,2)-1
$str&=$out_array[$i][$n]&@TAB
Next
$str&=@CRLF
Next
msgbox(0,0,$str)
func _format($num)
return StringFormat('%+04d',$num)&StringTrimLeft(StringFormat('%.3f',StringRegExpReplace($num,'(.+)(?=\.)','')),1)
EndFunc 本帖最后由 kevinch 于 2011-3-13 20:52 编辑
这种用excel处理好点吧,可以直接将格式修改成想要的这样。
直接用excel打开那个文本文件,将B,C列设置自定义数字格式+000.000;-000.000;0;@最后一列添加内容后排序,添加序号,然后保存即可 做个例子,最近也一直在研究AU3与office软件间的调用方法,附件供测试。{:face (396):} 本帖最后由 annybaby 于 2011-3-14 19:58 编辑
谢谢各位的回帖,慢慢研究几位的代码,特别感谢楼上用excel处理的那个test{:face (88):} ,我再慢慢尝试学习~~{:face (197):} {:face (229):}回复 10# kevinch
谢谢你的回帖,你的结果是我最想要的,(当然,其它回复的坛友也让我学了不少东西,{:face (239):})但是我想去掉中间的那个"-"可以吗?
我想应该是去掉其中的几行代码,但是我不知道去掉哪几行,我试了下去掉"-"那一行,发现输出也只是少了"-",第四部分与第五部分的距离变成了两个"TAB"键的宽度... 回复kevinch
谢谢你的回帖,你的结果是我最想要的,(当然,其它回复的坛友也让我学了不少 ...
annybaby 发表于 2011-3-14 20:42 http://www.autoitx.com/images/common/back.gif
如果求代码但不学会思考的话,代码求来又有何用??
8楼代码只需要在29行,30行之间增加一句:if $n=5 then ContinueLoop即可解决你的又一个问题. {:face (394):}{:face (394):}{:face (394):} 回复kevinch
谢谢你的回帖,你的结果是我最想要的,(当然,其它回复的坛友也让我学了不少 ...
annybaby 发表于 2011-3-14 20:42 http://www.autoitx.com/images/common/back.gif$excel=objcreate("excel.application")
;$excel.visible=true
$wb=$excel.workbooks.open(@scriptdir&"\test.txt")
$ws=$wb.worksheets(1)
for $row=1 to $ws.cells($ws.rows.count,1).end(3).row
$arr=stringsplit($excel.worksheetfunction.trim($ws.cells($row,1).value)," ")
for $column=1 to ubound($arr)-1
$ws.cells($row,$column)=$arr[$column]
next
next
with $ws
.columns("B:C").numberformatlocal="+000.000;-000.000;0;@"
.cells(1,1).currentregion.sort(.cells(1,5))
.columns("E").insert
$n=1
.cells(1,5)=1
for $row=2 to .cells(.rows.count,1).end(3).row
if .cells($row,7).value<>.cells($row-1,7).value then $n=$n+1
.cells($row,5)=$n
next
endwith
$excel.application.displayalerts=False
$wb.close(true)
$excel.quit这个试一下
页:
[1]