my788522 发表于 2012-2-4 17:04:31

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

本帖最后由 my788522 于 2012-2-5 10:45 编辑

$tst='0000]33333]4444]0000'

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

另外 以下这种情况....
$tst='0000]33333]4444]0000C]BBB]'
又该如何处理....

目前我使用stringinstr 不太理想 求指教

afan 发表于 2012-2-4 19:55:52

楼主的“stringinstr 不太理想”代码呢?

my788522 发表于 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

my788522 发表于 2012-2-4 21:23:27

但我这个无法处理第二种情况

my788522 发表于 2012-2-4 21:24:11

隐隐的感觉正则可以更好的提取 不过不太熟悉

sdc7 发表于 2012-2-5 00:39:32

本帖最后由 sdc7 于 2012-2-5 00:43 编辑

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

#include <Array.au3>
$s="]33333]4444]"
$begin = TimerInit()
$str=fenge($s)
$dif = TimerDiff($begin)
_ArrayDisplay($str,'执行时间'&$dif&"毫秒")
Func fenge($str)
Dim $str_l,$str_r
$strs=StringSplit ($s,"")
For $i=1 To $strs
    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=UBound($str_l)-1
$str_r=UBound($str_r)-1
;下面开始取字符串StringMid
Dim $str_all[$str_l]
For $i=0 To $str_l-1
$str_all[$i]=StringMid($s,$str_l[$str_l-$i],$str_r[$i+1]-$str_l[$str_l-$i]+1)
Next
Return $str_all
EndFunc

sdc7 发表于 2012-2-5 00:57:34

If $str_l[$str_l]<$str_lThen
        Dim $str_all[$str_l]
        For $i=0 To $str_l-1
        $str_all[$i]=StringMid($s,$str_l[$str_l-$i],$str_r[$i+1]-$str_l[$str_l-$i]+1)
        Next
        Return $str_all
Else
;找到边界
                For $i=1 To $str_l
                        If $str_l[$i]>$str_l Then
                                $b_l=$i-1
                                ExitLoop
                Next

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

没写完 困了!呵呵 自己补充吧!2个区分点已经找到 输出就成了

3mile 发表于 2012-2-5 01:19:31

好玩的东西,试下
Local $Str = '0000]33333]4444]5555]0000C]BBB]0000C]BBB]'
$time=TimerInit()
Local $Test = StringRegExp($str, '\[((?>[^\[\]]+)|((?R)))*\]', 4)
If Not @Error Then
        Local $Array,$Output,$Continus
       
        For $i = 0 To UBound($Test) - 1
                $Temp=$Test[$i]
                $Array[$i]=$Temp
        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&@CRLF
                        $Temp=$AA
                Else
                        ExitLoop
                EndIf               
        WEnd
Next
msgbox(0,TimerDiff($time),$Output)

netegg 发表于 2012-2-5 02:40:27

#include <array.au3>
$tst='0000]33333]4444]0000C]BBB]'
Local $aA1= StringSplit($tst, '[]', 2)
Local $aA2 = StringSplit($tst, '[', 2)
Local $aA3 = StringSplit($tst, ']', 2)
_ArrayDisplay($aA1)
_ArrayDisplay($aA2)
_ArrayDisplay($aA3)
对比下数组应该就行了

sdc7 发表于 2012-2-5 08:51:35

呵呵 同一电脑 高配置的测试下了 3笑的是0.48毫秒 我的是0.32毫秒`~~

my788522 发表于 2012-2-5 10:45:09

执行了一下 结果是一样的 执行效率基本是一样的
但3mile的感觉逻辑更明确 使用正则供学习的东西更广泛

3mile 发表于 2012-2-5 11:53:52

貌似逻辑有问题,比如像 [ xx aa] yy ] 这样具有同级[ ]的字符串有问题.
修正如下:
#include <Array.au3>
;]33333]4444]5555]
Local $Str = ']33333]4444]5555][ xx aa] yy ]'
$time=TimerInit()
Local $Test = StringRegExp($str, '\[((?>[^\[\]]+)|((?R)))*\]', 4)
If Not @Error Then
        Local $Array,$Output,$Continus
       
        For $i = 0 To UBound($Test) - 1
                $Temp=$Test[$i]
                $Array[$i]=$Temp
        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)
页: [1]
查看完整版本: (已解决)如何最优效率的多重提取符合条件的字符串(多括号嵌套对应关系)