Board logo

标题: [问题求助] 【已解决】vbs怎么求txt文件中所有指定字符后面数字的最小值和最大值 [打印本页]

作者: raozhao2008    时间: 2015-11-7 17:27     标题: 【已解决】vbs怎么求txt文件中所有指定字符后面数字的最小值和最大值

本帖最后由 pcl_test 于 2016-8-16 20:30 编辑

vbs怎么求txt文件中所有Z后面数字的最小值和最大值?说明:Z之前有一空格,之后是数字(包括正数负数),
另外此文件大小有10M以上,下列代码只是样例。以下是123.txt文件内容
  1. G00 X103.5 Y14.218 S3500 M03
  2. G43 Z19.429 H02
  3. Z-14.477
  4. G01 Z-14.77 F1500.
  5. X102.479 Z-15.012
  6. X86.047 Y30.86 Z-15.312
  7. G03 X87.002 Y27.983 Z-16.012 I-19.052 J-.001
  8. G01 Z-50.013
  9. Z30.
  10. G01 Z-14.977 F1500.
  11. X102.479 Z-15.012
  12. X86.047 Y30.86 Z-15.012
复制代码

作者: 依山居    时间: 2015-11-7 17:43

并没有说明输出格式。

我试试 python list排序。
作者: pcl_test    时间: 2015-11-7 17:55

本帖最后由 pcl_test 于 2015-11-8 09:59 编辑
  1. Dim arr()
  2. i = 0
  3. Set fso = CreateObject("Scripting.FileSystemObject")
  4. Set f = fso.OpenTextFile("测试.txt",1)
  5. Do While f.AtEndOfStream <> True
  6.     str = f.ReadLine
  7.     GetZ(str)
  8. Loop
  9. f.Close
  10. '调用Excel函数
  11. Set objExcel= CreateObject("Excel.Application")
  12. MsgBox "最大"&objExcel.Max(arr)&vbCrLf&"最小"&objExcel.Min(arr)
  13. Function GetZ(str)
  14.     Set regEx = New RegExp
  15.     regEx.Pattern = "\bZ(-?\d+\.?\d*)"
  16.     regEx.Global = True
  17.     If regEx.Test(str) Then
  18.         Set Matches = regEx.Execute(str)
  19.         For Each Match in Matches
  20.             ReDim Preserve arr(i)
  21.             arr(i) = CDbl(Match.SubMatches(0))
  22.             i = i+1
  23.         Next
  24.     End If
  25. End Function
复制代码

作者: 依山居    时间: 2015-11-7 19:07

  1. #求txt文件中所有Z后面数字的最小值和最大值
  2. #依山居 19:04 2015/11/7
  3. #题目来源: http://www.bathome.net/thread-38027-1-1.html
  4. zl=[]
  5. with open("a.txt") as f:
  6.         for l in f:
  7.                 txtline=l.rsplit()
  8.                 for ll in txtline:
  9.                         #print(ll)
  10.                         if ll[0]=="Z":
  11.                                 x=float(ll[1:])
  12.                                 zl.append(x)
  13.                                 
  14. #方法一:使用python内建的max min函数
  15. print("大: ",max(zl))
  16. print("小: ",min(zl))
  17. #方法二: 使用sorted排序后取首位和末尾元素。
  18. zl=sorted(zl)
  19. print("小: ",zl[0])
  20. print("大: ",zl[-1])
  21. #总结是不管是max 还是sort 比较的对象都应该统一是数字。
  22. #所以处理前需要先丢掉字母Z并转成浮点数。
  23. """
  24. 输出:
  25. 大:  30.0
  26. 小:  -50.013
  27. 小:  -50.013
  28. 大:  30.0
  29. """
复制代码

作者: 依山居    时间: 2015-11-7 19:17

楼主也是08年的帐号了。学门语言不过几周能入门了。
作者: winbat    时间: 2015-11-7 19:28

如@pcl_test 说的用 Excel 排序或编辑器升降排序这样可能行快些。
作者: 依山居    时间: 2015-11-8 03:30

  1. #python正则求txt文件中所有Z后面数字的最小值和最大值
  2. #依山居 2:23 2015/11/8
  3. #题目来源: http://www.bathome.net/thread-38027-1-1.html
  4. #这个版本改用正则表达式处理文本.
  5. import re
  6. def ftxt(txt="a.txt"):
  7.         #global zl
  8.         zl=[]
  9.         reg=re.compile("Z(-?\d*\.?\d*)")
  10.         with open(txt) as f:
  11.                 for line in f:
  12.                         regresult=re.findall(reg,line)
  13.                         if regresult:
  14.                                 for r in regresult:                                       
  15.                                        zl.append(float(r))
  16.         print(len(zl))
  17.         return zl
  18.         
  19. zl=ftxt()
  20. print(zl)
  21. #方法一:使用python内建的max min函数
  22. print("大: ",max(zl))
  23. print("小: ",min(zl))
  24. #方法二: 使用sorted排序后取首位和末尾元素。
  25. zl=sorted(zl)
  26. print("小: ",zl[0])
  27. print("大: ",zl[-1])
  28. #总结是不管是max 还是sort 比较的对象都应该统一是数字。
  29. #所以处理前需要先丢掉字母Z并转成浮点数。
  30. """
  31. 输出:
  32. 11
  33. [19.429, -14.477, -14.77, -15.012, -15.312, -16.012,
  34. -50.013, 30.0, -14.977, -15.012, -15.012]
  35. 大:  30.0
  36. 小:  -50.013
  37. 小:  -50.013
  38. 大:  30.0
  39. """
复制代码

作者: 依山居    时间: 2015-11-8 03:33

回复 3# pcl_test


    请问版主,为什么正则我写成Z(-?\d*\.?\d+)
发现也能匹配到 30. 呢?小数点后面并没有数字啊?
作者: pcl_test    时间: 2015-11-8 08:59

回复 8# 依山居

匹配的是Z30,30.0是因为float(r)所得
作者: WHY    时间: 2015-11-8 16:16

本帖最后由 WHY 于 2015-11-8 17:26 编辑

假设Z轴数据范围:-9999~9999
  1. Dim fso, objFile, objReg, Max, Min, str, n
  2. Set fso = CreateObject("Scripting.FileSystemObject")
  3. Set objFile = fso.OpenTextFile("a.txt")
  4. Set objReg = New RegExp
  5. objReg.Pattern = "\bZ(-?\d*\.?\d+)\b"
  6. Max = -9999 : Min = 9999
  7. While Not objFile.AtEndOfStream
  8.     str = objFile.ReadLine
  9.     If objReg.Test(str) Then
  10.         n = objReg.Execute(str)(0).SubMatches(0) * 1
  11.         If n > Max Then Max = n
  12.         If n < Min Then Min = n
  13.     End If
  14. Wend
  15. MsgBox "Max=" & Max & " Min=" & Min
复制代码

作者: raozhao2008    时间: 2015-11-9 13:43

回复 3# pcl_test

运行到此句时报错MsgBox "最大"&objExcel.Max(arr)&vbCrLf&"最小"&objExcel.Min(arr)
   类型不匹配‘objExcel.Max’
作者: raozhao2008    时间: 2015-11-9 13:58

找到一个JS的,速度非常快,可不知用这思路vbs能否实现
  1. path = "123.txt";
  2. fso = new ActiveXObject('Scripting.FileSystemObject');
  3. Znums = fso.OpenTextfile(path).ReadAll().match(/\bZ[-.\d]+\b/gi);
  4. Znums = Znums.join(',').replace(/Z/gi,'').split(',');
  5. Zmin = parseFloat(Znums[0]);
  6. for (i=0;i<Znums.length;i++) {
  7.     Znum = parseFloat(Znums[i]);
  8.     if(Znum<Zmin) Zmin=Znum;
  9. }
  10. Zmax = parseFloat(Znums[0]);
  11. for (i=0;i<Znums.length;i++) {
  12.     Znum = parseFloat(Znums[i]);
  13.     if(Znum>Zmax) Zmax=Znum;
  14. }
  15. WScript.Echo(Zmax + "/" + Zmin);
复制代码

作者: raozhao2008    时间: 2015-11-9 13:59

回复 10# WHY


   找到一个JS的,速度非常快,可不知用这思路vbs能否实现
作者: WHY    时间: 2015-11-9 14:41

回复 13# raozhao2008


    你认为10#思路和你的JS有区别吗?

如果txt文件小,当然可以用ReadAll 速度也会快些
  1. Dim fso, objReg, Max, Min, str, n
  2. Set fso = CreateObject("Scripting.FileSystemObject")
  3. str = fso.OpenTextFile("123.txt").ReadAll
  4. Set objReg = New RegExp
  5. objReg.Pattern = "\bZ(-?\d*\.?\d+)\b"
  6. objReg.Global = True
  7. For Each Match In objReg.Execute(str)
  8.     n = Match.SubMatches(0) * 1
  9.     If IsEmpty(Max) Or n > Max Then Max = n
  10.     If IsEmpty(Min) Or n < Min Then Min = n
  11. Next
  12. MsgBox "Max=" & Max & " Min=" & Min
复制代码

作者: 依山居    时间: 2015-11-11 10:35

  1. #python生成测试数据
  2. #依山居 10:07 2015/11/11
  3. import random
  4. import string
  5. import time
  6. start=time.time()
  7. az=string.ascii_uppercase
  8. out=open("b.txt","a+")
  9. for r in range(10000000):
  10.     ts=""
  11.     for s in range(1,random.randint(1,10)):
  12.             #razint=random.randint(0,25)
  13.             #raz=az[razint] #-_- random.choice()方法,简单也是等效的。
  14.             raz=random.choice(az)
  15.             rf=random.uniform(-99,999)
  16.             rf=round(rf,random.randint(0,4))
  17.             ts+=raz+str(rf)+" "
  18.     out.write(ts+"\n")
  19.             
  20. out.close()
  21. end=time.time()
  22. pt=end-start
  23. print("程序运行时间:",pt)
  24. try:
  25.     input("按回车退出")
  26. except SyntaxError:
  27.     pass
复制代码
处理几十M的文本都说觉得大了。生成了一千万行→_→"大数据"测试,文本也不过400M而已。反正几百M的文件都小于可用内存。一次读入完全不成问题。
作者: raozhao2008    时间: 2015-11-11 11:01

回复 15# 依山居


   多谢您回复,但我不会用python,不知这代码保存为什么格式,是否要编辑
作者: 依山居    时间: 2015-11-11 11:29

回复 9# pcl_test


    我也顺便给版主反馈一下。不需要逐行处理。
  1. #python正则求txt文件中所有Z后面数字的最小值和最大值3
  2. #依山居 10:57 2015/11/11
  3. #题目来源: http://www.bathome.net/thread-38027-1-1.html
  4. #这个版本使用read()直接读入整个文件内容然后正则匹配.
  5. #经过测试比逐行处理,速度快了3-5倍
  6. #总结:一次性读入正则匹配整个文件内容,处理速度快了3-5倍。
  7. #要不是自己起心生成数据来测试,就被带到沟里了。
  8. import time
  9. start=time.time()
  10. import re
  11. def ftxt(txt="b.txt"):
  12.         #global zl
  13.         zl=[]
  14.         reg=re.compile("Z(-?\d*\.?\d*)")
  15.         with open(txt) as f:
  16.                 c=f.read()
  17.                 regresult=re.findall(reg,c)
  18.                 if regresult:
  19.                         for r in regresult:
  20.                                 zl.append(float(r))                           
  21.         return zl
  22.         
  23. zl=ftxt()
  24. print("list长度: ",len(zl))
  25. #方法一:使用python内建的max min函数
  26. print("大: ",max(zl))
  27. print("小: ",min(zl))
  28. #方法二: 使用sorted排序后取首位和末尾元素。
  29. #还可以用zl.sort(reverse=True) zl.reverse() 排序
  30. zl=sorted(zl)
  31. print("小: ",zl[0])
  32. print("大: ",zl[-1])
  33. #总结是不管是max 还是sort 比较的对象都应该统一是数字。
  34. #所以处理前需要先丢掉字母Z并转成浮点数。
  35. end=time.time()
  36. pt=end-start
  37. print("程序运行时间:",pt)
  38. try:
  39.     input("按回车退出")
  40. except SyntaxError:
  41.     pass
  42. """
  43. 输出:
  44. list长度:  1921678
  45. 大:  999.0
  46. 小:  -99.0
  47. 小:  -99.0
  48. 大:  999.0
  49. 程序运行时间: 7.053403377532959
  50. ""
复制代码

作者: 依山居    时间: 2015-11-11 11:30

回复 16# raozhao2008


    下载安装python3
代码存为xx.py
作者: pcl_test    时间: 2016-8-16 20:53

第三方http://www.bathome.net/s/tool/index.html?key=gawk
  1. #*&cls&@gawk -f "%~f0" "1.txt">con&pause&exit
  2. {
  3.     for(i=1;i<=NF;i++){if($i~/Z-?[0-9]+\.?[0-9]*/)a[substr($i,2)]=substr($i,2)*1}
  4. }
  5. END{
  6.     len=asort(a,b); printf("最大%.3f\n最小%.3f\n",b[len],b[1]);
  7. }
复制代码





欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2