找回密码
 加入
搜索
查看: 3666|回复: 11

[AU3基础] (已解决)如何最优效率的多重提取符合条件的字符串(多括号嵌套对应关系)

  [复制链接]
发表于 2012-2-4 17:04:31 | 显示全部楼层 |阅读模式
本帖最后由 my788522 于 2012-2-5 10:45 编辑

$tst='0000[44444[333333[222222[111111]]33333]4444]0000'

如何提取出各对应多重方框内的内容和各括号的对应关系? 类似scite那样 对多括号嵌套的代码高亮
从最中心开始对应 例如以下是结果
$str[1]=[111111]
$str[2]=[222222[111111]]
$str[3]=[333333[222222[111111]]33333]
.....

另外 以下这种情况....
$tst='0000[44444[333333[222222[111111]]33333]4444]0000[BBBBBBB[CCCCCC[AAA]C]BBB]'
又该如何处理....

目前我使用stringinstr 不太理想 求指教
发表于 2012-2-4 19:55:52 | 显示全部楼层
楼主的“stringinstr 不太理想”代码呢?
 楼主| 发表于 2012-2-4 21:22:28 | 显示全部楼层
For $ffg= 1 To StringLen($str)
$kuohao1=StringInStr($str,"[",2,-1)
$kuohao2=StringInStr($str,"]",2,1)
If $kuohao1=0 Or $kuohao2=0 Then ExitLoop
$keyword=StringMid($str,$kuohao1+1,$kuohao2-$kuohao1-1)
MsgBox(0,"提取结果",$keyword)
$str=StringReplace($str,"["&$keyword&"]","")
Next
 楼主| 发表于 2012-2-4 21:23:27 | 显示全部楼层
但我这个无法处理第二种情况
 楼主| 发表于 2012-2-4 21:24:11 | 显示全部楼层
隐隐的感觉正则可以更好的提取 不过不太熟悉
发表于 2012-2-5 00:39:32 | 显示全部楼层
本帖最后由 sdc7 于 2012-2-5 00:43 编辑

执行时间基本1毫秒!···············不知道满意否!~ 只要配对都能识别! 忘看第2种,,没写 不过类似 分情况处理下就可以聊!。。。

#include <Array.au3>
$s="[44444[333333[222222[111111]]33333]4444]"
$begin = TimerInit()
$str=fenge($s)
$dif = TimerDiff($begin)
_ArrayDisplay($str,'执行时间'&$dif&"毫秒")
Func fenge($str)
Dim $str_l[1],$str_r[1]
$strs=StringSplit ($s,"")
For $i=1 To $strs[0]
    If $strs[$i]="[" Then
                $l=UBound($str_l)
                ReDim $str_l[$l+1]
                $str_l[$l]=$i ;存储[这个的位置
        EndIf
   
        If $strs[$i]="]" Then
                $r=UBound($str_r)
                ReDim $str_r[$r+1]
                $str_r[$r]=$i ;存储]这个的位置
        EndIf
        ;MsgBox(1,"",$l)
next
$str_l[0]=UBound($str_l)-1
$str_r[0]=UBound($str_r)-1
;下面开始取字符串StringMid
Dim $str_all[$str_l[0]]
For $i=0 To $str_l[0]-1
$str_all[$i]=StringMid($s,$str_l[$str_l[0]-$i],$str_r[$i+1]-$str_l[$str_l[0]-$i]+1)
Next
Return $str_all
EndFunc
发表于 2012-2-5 00:57:34 | 显示全部楼层
If $str_l[$str_l[0]]<$str_l[1]Then
        Dim $str_all[$str_l[0]]
        For $i=0 To $str_l[0]-1
        $str_all[$i]=StringMid($s,$str_l[$str_l[0]-$i],$str_r[$i+1]-$str_l[$str_l[0]-$i]+1)
        Next
        Return $str_all
Else
;找到边界
                For $i=1 To $str_l[0]
                        If $str_l[$i]>$str_l[1] Then
                                $b_l=$i-1
                                ExitLoop
                Next

                For $i=1 To $str_r[0]
                        If $str_r[$i]<$str_l[$str_l[0]] Then
                                $b_r=$i-1
                        ExitLoop
                Next
            ;输出
                Dim Dim $str_all[2][$str_l[0]]
                For $i=0 To $str_l[0]-1
                        $str_all[$i]=StringMid($s,$str_l[$str_l[0]-$i],$str_r[$i+1]-$str_l[$str_l[0]-$i]+1)
                Next
                Return $str_all
               
       
EndFunc

没写完 困了!呵呵 自己补充吧!2个区分点已经找到 输出就成了
发表于 2012-2-5 01:19:31 | 显示全部楼层
好玩的东西,试下
Local $Str = '0000[5555[44444[333333[222222[111111]]33333]4444]5555]0000[BBBBBBB[CCCCCC[AAA]C]BBB]0000[BBBBBBB[CCCCCC[AAA]C]BBB]'
$time=TimerInit()
Local $Test = StringRegExp($str, '\[((?>[^\[\]]+)|((?R)))*\]', 4)
If Not @Error Then
        Local $Array[UBound($Test)],$Output,$Continus
        
        For $i = 0 To UBound($Test) - 1
                $Temp=$Test[$i]
                $Array[$i]=$Temp[0]
        Next
EndIf

For $i=0 to UBound($Array)-1
        $Temp=$Array[$i]
        $output&=$Temp&@CRLF
        While 1
                If Not StringRegExp($Temp, '\[((?>[^\[\]]+)|((?R)))*\]', 0) Then ExitLoop                
                $AA=StringRegExp($Temp, '\[((?>[^\[\]]+)|((?R)))*\]', 3)
                If UBound($AA)>1 Then
                        $Output&=$AA[1]&@CRLF
                        $Temp=$AA[1]
                Else
                        ExitLoop
                EndIf                
        WEnd
Next
msgbox(0,TimerDiff($time),$Output)
发表于 2012-2-5 02:40:27 | 显示全部楼层
[au3]#include <array.au3>
$tst='0000[44444[333333[222222[111111]]33333]4444]0000[BBBBBBB[CCCCCC[AAA]C]BBB]'
Local $aA1= StringSplit($tst, '[]', 2)
Local $aA2 = StringSplit($tst, '[', 2)
Local $aA3 = StringSplit($tst, ']', 2)
_ArrayDisplay($aA1)
_ArrayDisplay($aA2)
_ArrayDisplay($aA3)[/au3]
对比下数组应该就行了
发表于 2012-2-5 08:51:35 | 显示全部楼层
呵呵 同一电脑 高配置的测试下了 3笑的是0.48毫秒 我的是0.32毫秒`~~
 楼主| 发表于 2012-2-5 10:45:09 | 显示全部楼层
执行了一下 结果是一样的 执行效率基本是一样的
但3mile的感觉逻辑更明确 使用正则供学习的东西更广泛
发表于 2012-2-5 11:53:52 | 显示全部楼层
貌似逻辑有问题,比如像 [ xx [aa [bbb] [ccc] aa] yy ] 这样具有同级[ ]的字符串有问题.
修正如下:
#include <Array.au3>
;[5555[44444[333333[222222[111111]]33333]4444]5555]
Local $Str = '[5555[44444[333333[222222[111111]]33333]4444]5555][ xx [aa [bbb] [ccc] aa] yy ]'
$time=TimerInit()
Local $Test = StringRegExp($str, '\[((?>[^\[\]]+)|((?R)))*\]', 4)
If Not @Error Then
        Local $Array[UBound($Test)],$Output,$Continus
        
        For $i = 0 To UBound($Test) - 1
                $Temp=$Test[$i]
                $Array[$i]=$Temp[0]
        Next
EndIf

For $i=0 to UBound($Array)-1
        $Temp=$Array[$i]
        While 1
                If Not StringRegExp($Temp,"\[|\]",0) Then ExitLoop
                $AA=StringRegExp($Temp, '(\[((?>[^\[\]]+)|(?R))*\])', 3)
                If UBound($AA)>1 Then
                        For $n=0 to UBound($AA)-1 Step 2
                                $Output&=$AA[$n]&@CRLF
                                $Temp=StringTrimRight(StringTrimLeft($AA[$n],1),1)
                        Next
                EndIf
        WEnd
Next
msgbox(0,TimerDiff($time),$Output)
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-9-21 21:55 , Processed in 0.081589 second(s), 23 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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