找回密码
 加入
搜索
楼主: 131738

[AU3基础] (已解决)请 afan 帮助修改正则替换代码, 谢谢!

 火... [复制链接]
发表于 2012-3-17 13:43:01 | 显示全部楼层
围观高手学习
 楼主| 发表于 2012-3-17 16:38:40 | 显示全部楼层
加上替换字符的转义,以防万一
afan 发表于 2012-3-15 20:14


找到耗时原因了,但不知如何解决:
测试 5 个 .txt  文件,分别为:
文件 1 需替换 4 行;
文件 2 需替换 8 行;
文件 3 需替换 13 行;
文件 4 需替换 4 行;
文件 5 需替换 11 行;

在你的代码中插入 MsgBox() 单步测试代码到第 15 行:
Func _UDF1();定向搜索文本替换
        Local $k, $i, $s0, $s1, $sFile
        
        For $k = 0 To UBound($aWinAPIEx) - 1
                $sFile = $aWinAPIEx[$k][2]
                If $sFile = '' Or Not FileExists($sFile) Then ContinueLoop
                Local $Str = String(FileRead($sFile)) ;将文件全部内容读入变量 $Str
                Local $Str1 = $Str

                For $i = 0 To UBound($aWinAPIEx) - 1
                        If $aWinAPIEx[$i][0] = '' Or $aWinAPIEx[$i][2] <> $sFile Then ContinueLoop
                        $s0 = StringRegExpReplace($aWinAPIEx[$i][0], '^\h*|\h*$', '') ; 对英文正则整理
                        $s1 = StringRegExpReplace($aWinAPIEx[$i][1], '\${|\$\d+|\\', '\\$0') ; 对中文正则整理
                        $Str = StringRegExpReplace($Str, '(?m)^\h*\Q' & $s0 & '\E\h*(?=\v|$)', $s1, 1);对变量 $Str(即整个文件)执行正则替换
MsgBox(262144,'替换后 ~' & $i,'测试变量:' & @lf & '$Str' & @lf & @lf & '变量返回:' & @lf & $Str & @lf & @lf & '@Error:' & @lf & @Error) ;### Debug MSGBOX
                Next
                If $Str = $Str1 Then ContinueLoop ;未替换一次
                Local $hFO = FileOpen($sFile, 2) ; 写入打开文件
                FileWrite($hFO, $Str) ; 将替换后的变量 $Str 的内容写入文件
                FileClose($hFO) ;关闭打开的文件
        Next
EndFunc   ;==>_UDF1
测试报告:
文件 1 有 4 行替换, 代码内层 For 循环的 $i 值在 ( 0 -- 3 ) 之间连续循环, 重复 4 个周期 ( 0 -- 3 ),
但第一次的 $i( 0--3 ) 循环完成后, 在目录资源管理器中, 文件的修改日期立即变化到当前的日期时间;
此时打开文件 1 (脚本暂停在第 2 次循环开始处), 查看文件已正确完成替换!
其后的 3 次 $i( 0--3 ) 循环 , 目录资源管理器中文件的修改日期无任何变化!

第 4 次循环从 $i = 4 开始,处理文件 2
相应 $i 在 ( 4--11 ) 之间, 由于需 8 行替换, $i( 4--11 ) 连续重复 8 个周期循环,
文件的修改日期同文件 1 一样, 也是在第一次循环完成后立即变化!
其余 7 次为无功循环, (或是重复读写操作).

文件 3 在 $i = (12--24) 之间处理;
文件 4 在 $i = (25--29) 之间处理;
文件 5 在 $i = (30--40) 之间处理;
文件的改日期同文件 1 , 2 一样, 也是在第一次循环完成后立即变化! 其余循环看不出什么结果!

结论: 视文件需替换的行数决定 $i 的循环周期值;如文件 3 有 13 行替换, 相应 $i 分别为 (12--24) 13个值
行数又决定循环周期(如 12--24 )的重复次数,行数越多,重复循环也越多,
这个重复循环应该是在重复读写操作,也就是耗时长的原因吧!

试图用 For $i = 0 To  _FileCountLines($sFile){返回当前文件行数} 循环,
结果 5 个文件只能完成 2 个后脚本退出!

说了这么多,不知你看明白没有?
发表于 2012-3-17 21:11:34 | 显示全部楼层
找到耗时原因了,但不知如何解决:
测试 5 个 .txt  文件,分别为:
文件 1 需替换 4 行;
文件 2 需替换 ...
131738 发表于 2012-3-17 16:38



    这个是肯定的,因为写这个的时候并不知道你的完整数组定义~ 认为你的文件不一定处在连续的数组元素索引中,所以需要两次循环,外循环为判断文件是否为同一文件,内循环为在当前处理的文件中进行循环替换。
如果文件是连续的数组索引那就容易多了~
发表于 2012-3-17 21:14:43 | 显示全部楼层
总之如何定义数组,直接影响到如何写替换。
 楼主| 发表于 2012-3-17 21:17:31 | 显示全部楼层
这个是肯定的,因为写这个的时候并不知道你的完整数组定义~ 认为你的文件不一定处在连续的数组元 ...
afan 发表于 2012-3-17 21:11


我写了个重编索引的脚本,可以整理同一文件在连续索引段。
发表于 2012-3-17 21:47:35 | 显示全部楼层
本帖最后由 afan 于 2012-3-17 22:29 编辑

回复 66# 131738


   那就试试这个
Func _UDF1()
        Local $k, $s0, $s1, $sFile
        For $k = 0 To UBound($aWinAPIEx) - 1
                If $aWinAPIEx[$k][0] = '' Then ContinueLoop
                $sFile = $aWinAPIEx[$k][2]        ;当前处理的文件
                Local $Str = String(FileRead($sFile)), $Str1 = $Str, $i = $k
                While 1
                        $s0 = StringRegExpReplace($aWinAPIEx[$i][0], '^\h*|\h*$', '')
                        $s1 = StringRegExpReplace($aWinAPIEx[$i][1], '\${|\$\d+|\\', '\\$0')
                        $Str = StringRegExpReplace($Str, '(?m)^\h*\Q' & $s0 & '\E\h*(?=\v|$)', $s1, 1)
                        If $aWinAPIEx[$i + 1][2] <> $sFile Then ExitLoop        ;如果下一个文件不是当前文件则退出该文件的全部操作
                        $i += 1        ;为了接着处理当前文件的下一组数据
                Wend
                $k = $i        ;这样就不会多于的循环了
                If $Str = $Str1 Then ContinueLoop ;未替换一次
                Local $hFO = FileOpen($sFile, 2)
                FileWrite($hFO, $Str)
                FileClose($hFO)
        Next
EndFunc   ;==>_UDF1
 楼主| 发表于 2012-3-17 21:52:24 | 显示全部楼层
回复  131738


   那就试试这个
afan 发表于 2012-3-17 21:47

刚加了 2 行代码,貌似可以了...
Func _UDF1();定向搜索文本替换
    Local $k, $i, $s0, $s1, $sFile, $sFileX
        
    For $k = 0 To UBound($aWinAPIEx) - 1
        $sFile = $aWinAPIEx[$k][2]
                If $sFile = $sFileX Then ContinueLoop; 添加代码
        If $sFile = '' Or Not FileExists($sFile) Then ContinueLoop
        Local $Str = String(FileRead($sFile)) ;将文件全部内容读入变量 $Str
                Local $Str1 = $Str

        For $i = 0 To UBound($aWinAPIEx) - 1
            If $aWinAPIEx[$i][0] = '' Or $aWinAPIEx[$i][2] <> $sFile Then ContinueLoop
            $s0 = StringRegExpReplace($aWinAPIEx[$i][0], '^\h*|\h*$', '') ; 对英文正则整理
            $s1 = StringRegExpReplace($aWinAPIEx[$i][1], '\${|\$\d+|\\', '\\$0') ; 对中文正则整理
            $Str = StringRegExpReplace($Str, '(?m)^\h*\Q' & $s0 & '\E\h*(?=\v|$)', $s1, 1);对变量 $Str(即整个文件)执行正则替换
MsgBox(262144,'替换后 ~' & $k & '  ' & $i,'测试变量:' & @lf & '$Str' & @lf & @lf & '变量返回:' & @lf & $Str & @lf & @lf & '@Error:' & @lf & @Error) ;### Debug MSGBOX
                        $sFileX = $sFile; 添加代码
                Next
        If $Str = $Str1 Then ContinueLoop ;未替换一次
        Local $hFO = FileOpen($sFile, 2) ; 写入打开文件
        FileWrite($hFO, $Str) ; 将替换后的变量 $Str 的内容写入文件
                FileClose($hFO) ;关闭打开的文件
    Next
EndFunc   ;==>_UDF1
 楼主| 发表于 2012-3-17 21:54:18 | 显示全部楼层
回复 67# afan

再看看这个代码,头脑较笨,好长时间才能看懂代码...
 楼主| 发表于 2012-3-17 22:08:10 | 显示全部楼层
回复  131738


   那就试试这个
afan 发表于 2012-3-17 21:47


这个 $i += 1 出现跳号,导致漏替换行,
谢谢! 暂时结束这个问题,我再整体测试一遍,比较耗时....
发表于 2012-3-17 22:13:05 | 显示全部楼层
这个 $i += 1 出现跳号,导致漏替换行,
谢谢! 暂时结束这个问题,我再整体测试一遍,比较耗时....
131738 发表于 2012-3-17 22:08



    是试我 67# 的代码,怎么又被你改成 for 了……
发表于 2012-3-17 22:23:43 | 显示全部楼层
这个 $i += 1 出现跳号,导致漏替换行,
谢谢! 暂时结束这个问题,我再整体测试一遍,比较耗时....
131738 发表于 2012-3-17 22:08



    我懂你的意思了,67# 修改了下,再试试~
 楼主| 发表于 2012-3-17 23:42:10 | 显示全部楼层
我懂你的意思了,67# 修改了下,再试试~
afan 发表于 2012-3-17 22:23


67# 没无功循环,也不跳号了,但最后一个文件回写失败。。。谢谢!别再费神了,
明天整理索引后,整体测试,有问题再请教。。。
发表于 2012-3-18 12:30:36 | 显示全部楼层
回复 73# 131738


    没有测试环境还真不好弄,现在应该OK了
Func _UDF1()
        Local $k, $s0, $sFile, $iMax = UBound($aWinAPIEx) - 1
        For $k = 0 To $iMax
                If $aWinAPIEx[$k][0] = '' Then ContinueLoop
                $sFile = $aWinAPIEx[$k][2]        ;当前处理的文件
                Local $Str = String(FileRead($sFile)), $Str1 = $Str
                While 1
                        $s0 = StringRegExpReplace($aWinAPIEx[$k][0], '^\h*|\h*$', '')
                        $s1 = StringRegExpReplace($aWinAPIEx[$k][1], '\${|\$\d+|\\', '\\$0')
                        $Str = StringRegExpReplace($Str, '(?m)^\h*\Q' & $s0 & '\E\h*(?=\v|$)', $s1, 1)
                        If ($k = $iMax) Or ($aWinAPIEx[$k + 1][2] <> $sFile) Then ExitLoop        ;如果下一个文件不是当前文件则退出该文件的全部操作
                        $k += 1        ;为了接着处理当前文件的下一组数据,不会多余的循环
                Wend
                If $Str = $Str1 Then ContinueLoop ;未替换一次
                Local $hFO = FileOpen($sFile, 2)
                FileWrite($hFO, $Str)
                FileClose($hFO)
        Next
EndFunc   ;==>_UDF1
 楼主| 发表于 2012-3-18 16:14:35 | 显示全部楼层
回复  131738


    没有测试环境还真不好弄,现在应该OK了
afan 发表于 2012-3-18 12:30


谢谢你助人的热心!!!68 楼的代码已回到正常,由前次的 16 分多回到 1 分 45 秒
这楼的代码我再测试后回复你,如有问题,我打包附件给你
 楼主| 发表于 2012-3-18 16:35:31 | 显示全部楼层
回复  131738


    没有测试环境还真不好弄,现在应该OK了
afan 发表于 2012-3-18 12:30


完全 OK 了,关闭此贴,正则替换的后续其它问题以后另开贴请教.
太热心了,我都感觉有点对不起你,只提问题,不提供测试资源,抱歉了!谢谢!!!
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-5-10 19:13 , Processed in 0.075064 second(s), 13 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表