dtooboss 发表于 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 不能处理多行的情况
无奈中.......

love5173 发表于 2011-4-27 15:15:49

回复 1# dtooboss
10万行么? 这个真快不了呢!
我可以写个不是数组替换的,但是也快不到哪里去!
我写完给你测试吧

love5173 发表于 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)
EndIf
Next
FileOpen("c.txt",2+8)
FileWrite("c.txt",$filestr1)
FileClose("c.txt")
如果速度快的话跟我说一下,如果还不如你的就算了

hzxymkb 发表于 2011-4-27 16:34:29

看到这东西头都大了!无解!

love5173 发表于 2011-4-27 17:47:33

见不得,写的东西无人问津,楼主给个答复,我手头没有10万行的测试文本,今天如果不回复,我将删除我上面的代码,反正也没人看

dtooboss 发表于 2011-4-27 20:21:12

见不得,写的东西无人问津,楼主给个答复,我手头没有10万行的测试文本,今天如果不回复,我将删除我上面的 ...
love5173 发表于 2011-4-27 17:47 http://www.autoitx.com/images/common/back.gif


    刚回来!!
sorry 了!!
很好用,很快,学习了......
对正则我是一塌糊涂......
再次感谢!半小时跑完了。

love5173 发表于 2011-4-27 20:29:30

回复 6# dtooboss
{:face (280):}很欣慰,如果说没有重复的话18行 只叫他替换一次就可以,速度能更快

3mile 发表于 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)

dtooboss 发表于 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 完成::1

3mile 发表于 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)

love5173 发表于 2011-4-28 00:26:36

回复 9# dtooboss
3M的思路很好,但是逻辑上有点问题,a与b行数未必完全相等,另外行与行也不是完全匹配的
我在运行的时候提示错误的数组或者数组超出界限。
因为牵扯到字典,对象这块我实在是头疼,所以评论的未必准确,希望3M再来改进代码,我还在学习中

3mile 发表于 2011-4-28 13:00:40

回复 11# love5173
楼主都跑了,我们还瞎忙些什么呢?

dtooboss 发表于 2011-4-28 15:12:32

回复love5173
楼主都跑了,我们还瞎忙些什么呢?
3mile 发表于 2011-4-28 13:00 http://www.autoitx.com/images/common/back.gif

没跑......
刚上线
3M 大大的10楼的代码太快了.....+>15:06:58 AutoIT3.exe 完成::0
+>15:06:59 ACNWrapper 完成..
>退出代码: 0        运行时间: 4.959 秒
叫我无地自容呀....

love5173 发表于 2011-4-28 15:55:27

本帖最后由 love5173 于 2011-4-28 16:08 编辑

代码改了没发现

love5173 发表于 2011-4-28 16:05:58

本帖最后由 love5173 于 2011-4-28 17:36 编辑

效率很强大,
始终在对象的门前不得而入,我也想举一反三,只是要知道这些个对象的具体作用太费劲了,不知道怎么入门
现在只能看一个例子仿造一个例子
{:face (229):}
页: [1]
查看完整版本: 多行替换求助【已解决】