找回密码
 加入
搜索
查看: 4658|回复: 14

[AU3基础] 多行替换求助【已解决】

  [复制链接]
发表于 2011-4-27 12:25:54 | 显示全部楼层 |阅读模式
本帖最后由 dtooboss 于 2011-4-29 16:13 编辑

有两个文本格式如下
a.txt
/====6ab35c8edfeb636d====/                   ;靠这行定位
Place {0.Number}                                                           ;需要替换
 buildings in one Kingdom                                               ;的内容
/====93665e35805b3c78====/
Keep
/====92df8cef9921e602====/
Place {0.Number} buildings in one Kingdom
/====167d6c60a859c3dd====/
Castle
/====19693b776d70b103====/
Place {0.Number} buildings 

in one Kingdom
/====d4963c447a76e4d2====/
Settlement
/====bf0b13e72dd9b858====/
Place {0.Number} buildings
 in one Kingdom
/====4a10481e23ed43f7====/
Village
/====8cdff7665396fd88====/
Annex all Foreign Territories
/====3eb89602f1c19d47====/
Possessor of All
.....................10万行左右
b.txt
/====6ab35c8edfeb636d====/
在一个王国内修造 {0.Number} 栋建筑
/====93665e35805b3c78====/
保持
/====92df8cef9921e602====/
在一个王国内修造 {0.Number} 栋建筑
/====167d6c60a859c3dd====/
城堡
/====19693b776d70b103====/
在一个王国内修造 {0.Number} 栋建筑
/====d4963c447a76e4d2====/
居留地
/====bf0b13e72dd9b858====/
在一个王国内修造 {0.Number} 栋建筑
/====4a10481e23ed43f7====/
村庄
/====8cdff7665396fd88====/
兼并所有外国领土
/====3eb89602f1c19d47====/
持有人
/====bd38fb39ea69bc27====/
兼并 {0.Number} 块外国领土
/====c06608248be5375e====/
领主
/====6f71522690b134e6====/
兼并 {0.Number} 块外国领土


........ 10万行左右
请问如何根据  /====xxxxxxxxxxxxxxxx====/ 快速把b.txt 的相应位置的文本在 a.txt中查找定位并替换?

以下是我写的数组方式的替换,不过使用时间太长,几个小时都跑不了一半。
希望高手能帮忙看看:
#include <file.au3>
#include <Array.au3>

$file = 'a.txt' ;10万多行行数和b.txt不等
$filehh = 'b.txt';10万多行行数和a.txt不等

$filestr = FileRead($filehh)
$filestr1 = FileRead($file)

$array = StringRegExp($filestr, "(?s)(/====\w\w\w\w\w\w\w\w\w\w\w\w\w\w\w\w====/)([\s\S]*?)(?=/====\w\w\w\w\w\w\w\w\w\w\w\w\w\w\w\w====/)", 3)
$array1 = StringRegExp($filestr1, "(?s)(/====\w\w\w\w\w\w\w\w\w\w\w\w\w\w\w\w====/)([\s\S]*?)(?=/====\w\w\w\w\w\w\w\w\w\w\w\w\w\w\w\w====/)", 3)
;_ArrayDisplay($array)
;_ArrayDisplay($array1)

for $i = 0 to UBound($array) - 1
        
        $iIndex = _ArraySearch($array1, $array[$i], 0, 0, 0, 1);在数组 $array1 中找到 /====xxxxxxxxxxxxxxxx====/ 的索引
                $i = $i + 1 ;跳过一个替换数据的索引
                $iIndex = $iIndex + 1 ;需要替换的应该是匹配的下一个索引
_ArrayInsert($array1, $iIndex , $array[$i]) ;在相应索引中替换值

Next

; 把全部替换后的数组写入新文件
For $x = 0 to UBound($array1) - 1
ConsoleWrite($x&@CRLF )
FileWrite('c.txt',$array1[$x]&@crlf)
next
以上代码能正确运行,就是越往后越慢。
afan大大的 _FileSRER2Line UDF 不能处理多行的情况
无奈中.......
发表于 2011-4-27 15:15:49 | 显示全部楼层
回复 1# dtooboss
10万行么? 这个真快不了呢!
我可以写个不是数组替换的,但是也快不到哪里去!
我写完给你测试吧
发表于 2011-4-27 15:56:29 | 显示全部楼层
本帖最后由 love5173 于 2011-4-27 16:24 编辑

#Region ;**** 参数创建于 ACNWrapper_GUI ****
#AutoIt3Wrapper_outfile=..\..\xixihaha.exe
#EndRegion ;**** 参数创建于 ACNWrapper_GUI ****
#include <file.au3>
#include <Array.au3>
$file1 = 'a.txt' ;10万多行行数和b.txt不等
$file2 = 'b.txt';10万多行行数和a.txt不等
FileOpen($file1)
FileOpen($file2)
$filestr1 = FileRead($file1)
$filestr2 = FileRead($file2)
FileClose($file1)
FileClose($file2)
$array1 = StringRegExp($filestr1,'/.*/', 3)
for $i = 0 to UBound($array1) - 1
      $array2=StringRegExp($filestr2,$array1[$i]&'([^/]+)',1)
If Not @error Then
        $filestr1=StringRegExpReplace($filestr1,$array1[$i]&'[^/]+',$array1[$i]&$array2[0])
EndIf
Next
FileOpen("c.txt",2+8)
FileWrite("c.txt",$filestr1)
FileClose("c.txt")

如果速度快的话跟我说一下,如果还不如你的就算了

评分

参与人数 1金钱 +10 贡献 +5 收起 理由
dtooboss + 10 + 5 thank you

查看全部评分

发表于 2011-4-27 16:34:29 | 显示全部楼层
看到这东西头都大了!无解!
发表于 2011-4-27 17:47:33 | 显示全部楼层
见不得,写的东西无人问津,楼主给个答复,我手头没有10万行的测试文本,今天如果不回复,我将删除我上面的代码,反正也没人看
 楼主| 发表于 2011-4-27 20:21:12 | 显示全部楼层
见不得,写的东西无人问津,楼主给个答复,我手头没有10万行的测试文本,今天如果不回复,我将删除我上面的 ...
love5173 发表于 2011-4-27 17:47



    刚回来!!
sorry 了!!
很好用,很快,学习了......
对正则我是一塌糊涂......
再次感谢!半小时跑完了。
发表于 2011-4-27 20:29:30 | 显示全部楼层
回复 6# dtooboss
很欣慰,如果说没有重复的话18行 只叫他替换一次就可以,速度能更快
发表于 2011-4-27 23:31:20 | 显示全部楼层
试下效率
#include <array.au3>

$file_a=FileRead("a.txt")
$file_b=FileRead("b.txt")

if StringTrimRight($file_a,1)<>"/" then $file_a=$file_a&@crlf&"/"
if StringTrimRight($file_b,1)<>"/" then $file_b=$file_b&@crlf&"/"

$file_a_array=StringRegExp($file_a,'(?ms)(\/.*?/\s+)(.*?)(?=\s+/)',3)
$file_b_array=StringRegExp($file_b,'(?ms)(\/.*?/\s+)(.*?)(?=\s+/)',3)

local $a_Dic=objcreate("scripting.dictionary")
local $b_Dic=objcreate("scripting.dictionary")

for $i=1 to UBound($file_a_array)-1 step 2
        $a_Dic.item($file_a_array[$i-1])=$file_a_array[$i]
        $b_Dic.item($file_b_array[$i-1])=$file_b_array[$i]
Next

for $i=0 to UBound($file_a_array)-1 step 2
        if $b_dic.Exists($file_a_array[$i]) Then
                ;msgbox(0,0,$file_a_array[$i]&@crlf&$b_dic.item($file_a_array[$i]))
                $file_a_array[$i+1]=$b_dic.item($file_a_array[$i])
        EndIf
Next

$str=StringRegExpReplace(_ArrayToString($file_a_array,@CRLF),'\n\r','')
filewrite("c.txt",$str)

评分

参与人数 1金钱 +30 收起 理由
love5173 + 30 学习了

查看全部评分

 楼主| 发表于 2011-4-27 23:46:30 | 显示全部楼层
8楼高手的代码出奇的快,提取只用了几分钟。
不过后面报错无法运行了....
E:\hh\111.au3 (17) : ==> ?????????????.:
$b_Dic.item($file_b_array[$i-1])=$file_b_array[$i]
$b_Dic.item(^ ERROR
->23:43:03 AutoIT3.exe 完成:[CODE]:1
发表于 2011-4-28 00:06:19 | 显示全部楼层
回复 9# dtooboss
两个文本结构不一样吗?
那试下这个.
#include <array.au3>

$file_a=FileRead("a.txt")
$file_b=FileRead("b.txt")

if StringTrimRight($file_a,1)<>"/" then $file_a=$file_a&@crlf&"/"
if StringTrimRight($file_b,1)<>"/" then $file_b=$file_b&@crlf&"/"

$file_a_array=StringRegExp($file_a,'(?ms)(\/.*?/\s+)(.*?)(?=\s+/)',3)
$file_b_array=StringRegExp($file_b,'(?ms)(\/.*?/\s+)(.*?)(?=\s+/)',3)

local $a_Dic=objcreate("scripting.dictionary")
local $b_Dic=objcreate("scripting.dictionary")

for $i=1 to UBound($file_a_array)-1 step 2
        $a_Dic.item($file_a_array[$i-1])=$file_a_array[$i]        
        ;$b_Dic.item($file_b_array[$i-1])=$file_b_array[$i]
Next

FOR $i=1 to UBound($file_b_array-1) step 2
        $b_Dic.item($file_b_array[$i-1])=$file_b_array[$i]
Next

for $i=0 to UBound($file_a_array)-1 step 2
        if $b_dic.Exists($file_a_array[$i]) Then
                ;msgbox(0,0,$file_a_array[$i]&@crlf&$b_dic.item($file_a_array[$i]))
                $file_a_array[$i+1]=$b_dic.item($file_a_array[$i])
        EndIf
Next

$str=StringRegExpReplace(_ArrayToString($file_a_array,@CRLF),'\n\r','')
filewrite("c.txt",$str)

评分

参与人数 2金钱 +40 贡献 +1 收起 理由
dtooboss + 10 + 1
love5173 + 30 学习了

查看全部评分

发表于 2011-4-28 00:26:36 | 显示全部楼层
回复 9# dtooboss
3M的思路很好,但是逻辑上有点问题,a与b行数未必完全相等,另外行与行也不是完全匹配的
我在运行的时候提示错误的数组或者数组超出界限。
因为牵扯到字典,对象这块我实在是头疼,所以评论的未必准确,希望3M再来改进代码,我还在学习中
发表于 2011-4-28 13:00:40 | 显示全部楼层
回复 11# love5173
楼主都跑了,我们还瞎忙些什么呢?
 楼主| 发表于 2011-4-28 15:12:32 | 显示全部楼层
回复  love5173
楼主都跑了,我们还瞎忙些什么呢?
3mile 发表于 2011-4-28 13:00


没跑......
刚上线
3M 大大的10楼的代码太快了.....
+>15:06:58 AutoIT3.exe 完成:[CODE]:0
+>15:06:59 ACNWrapper 完成..
>退出代码: 0        运行时间: 4.959 秒
叫我无地自容呀....
发表于 2011-4-28 15:55:27 | 显示全部楼层
本帖最后由 love5173 于 2011-4-28 16:08 编辑

代码改了没发现
发表于 2011-4-28 16:05:58 | 显示全部楼层
本帖最后由 love5173 于 2011-4-28 17:36 编辑

效率很强大,
始终在对象的门前不得而入,我也想举一反三,只是要知道这些个对象的具体作用太费劲了,不知道怎么入门
现在只能看一个例子仿造一个例子
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-10-2 06:42 , Processed in 0.085672 second(s), 20 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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