Jump to content

Remove nested strings


 Share

Recommended Posts

I need to delete from the list of strings that are nested in relation to others.

Example

; #include <Array.au3>

$sText= _
'[HKEY_CLASSES_ROOT\.wav]' & @CRLF & _
'[HKEY_CLASSES_ROOT\.wav\PersistentHandler]' & @CRLF & _
'[HKEY_CLASSES_ROOT\wavfile\DefaultIcon]' & @CRLF & _
'[HKEY_CLASSES_ROOT\wavfile\shell]' & @CRLF & _
'[HKEY_CLASSES_ROOT\wavfile\shell\open\command]'
MsgBox(0, "1", $sText)


$aReg = StringRegExp($sText, "(?m)^(\[HK.*?\])", 3)
; _ArrayDisplay($aReg, 'aReg')
; If StringRight($sText, 2)<>@CRLF Then $sText &= @CRLF

For $i = 0 To UBound($aReg) - 1
$sText = StringRegExpReplace($sText, StringRegExpReplace(StringTrimRight($aReg[$i], 1), "[][{}()*+?.\\^$|=<>#]", "\\$0") & '(\\.+|\])\r\n', "")
If @extended Then $sText &= @CRLF & $aReg[$i]
Next
MsgBox(0, "2", $sText)

But it is not as fast as I'd like. If more than 1000 lines

Link to comment
Share on other sites

Wow, that's a pretty complex example. It would be pretty difficult and time consuming to performance-tune it, from what I see, and there's a good chance that performance tuning the regexp would not yield a good performance benefit. If it were me, I'd chunk it into several small pieces and parallelize it.

Link to comment
Share on other sites

that is a helluva regexp, dont know that this will be faster...or if you need that trailing bracket back:

#include <Array.au3>

$sText= _
'[HKEY_CLASSES_ROOT.wav]' & @CRLF & _
'[HKEY_CLASSES_ROOT.wavPersistentHandler]' & @CRLF & _
'[HKEY_CLASSES_ROOTwavfileDefaultIcon]' & @CRLF & _
'[HKEY_CLASSES_ROOTwavfileshell]' & @CRLF & _
'[HKEY_CLASSES_ROOTwavfileshellopencommand]'

$sArray = stringsplit($sText , "]" , 2)

for $i = ubound ($sArray) - 1 to 0 step - 1
for $n = ubound ($sArray) - 1 to 0 step - 1
If $i <> $n Then
If stringinstr($sArray[$n] , $sArray[$i]) Then _ArrayDelete($sArray , $n)
Endif
next
next

_ArrayDisplay($sArray)

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

What are the rules of the game?

Why wouldn't your example return just these 2 strings:

[HKEY_CLASSES_ROOT.wav]
[HKEY_CLASSES_ROOTwavfile]
?

#include <Array.au3>
Global $sText= _
'[HKEY_CLASSES_ROOT.wav]' & @CRLF & _
'[HKEY_CLASSES_ROOT.wavPersistentHandler]' & @CRLF & _
'[HKEY_CLASSES_ROOTwavfileDefaultIcon]' & @CRLF & _
'[HKEY_CLASSES_ROOTwavfileshell]' & @CRLF & _
'[HKEY_CLASSES_ROOTwavfileshellopencommand]'
MsgBox(0, "1", $sText)

Local $aArray = StringSplit($sText , @CRLF, 1)
Local $i = 1
For $j = 2 to $aArray[0]
    If Not StringInStr($aArray[$j], StringReplace($aArray[$i], "]", "")) Then
        $i +=1
        $aArray[$i] = $aArray[$j]
    Endif
Next
$aArray[0] = $i
ReDim $aArray[$i + 1]
_ArrayDisplay($aArray)
Edited by Spiff59
Link to comment
Share on other sites

Thanks for the metrics. I've heard repeatedly that the _array stuff is slower than string actions, apparently much.

..and 1.64 is too slow?

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

Spiff59

I early was delighted. Deletes not correctly sometimes

#include <Array.au3>
Global $sText= _
'[HKEY_LOCAL_MACHINESOFTWAREClasseszzz]' & @CRLF & _
'[HKEY_LOCAL_MACHINESOFTWAREClasseszzz.1]' & @CRLF & _
'[HKEY_LOCAL_MACHINESOFTWAREClassesxxx]' & @CRLF & _
'[HKEY_LOCAL_MACHINESOFTWAREClassesxxx.1]'
MsgBox(0, "1", $sText)

$timer = TimerInit()
Local $aArray = StringSplit($sText , @CRLF, 1)
Local $i = 1
For $j = 2 to $aArray[0]
    If Not StringInStr($aArray[$j], StringReplace($aArray[$i], "]", "")) Then
        $i +=1
        $aArray[$i] = $aArray[$j]
    Endif
Next
$aArray[0] = $i
ReDim $aArray[$i + 1]
_ArrayDisplay($aArray)

Still problem

#include <Array.au3>
$sText= _
'[HKEY_CLASSES_ROOT.wavPersistentHandler]' & @CRLF & _
'[HKEY_CLASSES_ROOT.wav]'
Edited by AZJIO
Link to comment
Share on other sites

Spiff59

I early was delighted. Deletes not correctly sometimes

#include <Array.au3>
Global $sText= _
'[HKEY_LOCAL_MACHINESOFTWAREClasseszzz]' & @CRLF & _
'[HKEY_LOCAL_MACHINESOFTWAREClasseszzz.1]' & @CRLF & _
'[HKEY_LOCAL_MACHINESOFTWAREClassesxxx]' & @CRLF & _
'[HKEY_LOCAL_MACHINESOFTWAREClassesxxx.1]'
Changing the Stringreplace to "StringReplace($aArray[$i], "]", "")" seems to resolve the issue with this data.

Still problem

#include <Array.au3>
$sText= _
'[HKEY_CLASSES_ROOT.wavPersistentHandler]' & @CRLF & _
'[HKEY_CLASSES_ROOT.wav]'
Aren't the keys returned already sorted? If not, I guess a pre-sort would be needed.
Link to comment
Share on other sites

I see "" is ASCII 92 and "]" is 93 :(

That complicates it even more.

I'm not sure if this will be slow as molasses or not...

#include <Array.au3>
Global $sText = _
'[HKEY_CLASSES_ROOT.wavPersistentHandler]' & @CRLF & _
'[HKEY_CLASSES_ROOT.wav]' & @CRLF & _
'[HKEY_CLASSES_ROOTwavfileDefaultIcon]' & @CRLF & _
'[HKEY_CLASSES_ROOTwavfileshell2]' & @CRLF & _
'[HKEY_CLASSES_ROOTwavfileshell]' & @CRLF & _
'[HKEY_CLASSES_ROOTwavfileshellopencommand]'
MsgBox(0, "1", $sText)

Local $aArray = StringSplit($sText , "]" & @CRLF, 1)
_ArraySort($aArray, 0, 1)
_ArrayDisplay($aArray)
Local $i = 1
For $j = 2 to $aArray[0]
    If Not StringInStr($aArray[$j], $aArray[$i] & "") Then
        $aArray[$i] &= "]"
        $i += 1
        $aArray[$i] = $aArray[$j]
    Endif
Next
$aArray[$i] &= "]"
$aArray[0] = $i
ReDim $aArray[$i + 1]
_ArrayDisplay($aArray)
Link to comment
Share on other sites

Spiff59

Sorting does not give the desired effect

#include <Array.au3>
Global $sText = _
'[HKEY_CLASSES_ROOTzzz]' & @CRLF & _
'[HKEY_CLASSES_ROOTzzz.2]' & @CRLF & _
'[HKEY_CLASSES_ROOTzzzky1]' & @CRLF & _
'[HKEY_CLASSES_ROOTzzzky]'
MsgBox(0, "1", $sText)

Local $aArray = StringSplit($sText , "]" & @CRLF, 1)
_ArraySort($aArray, 0, 1)
_ArrayDisplay($aArray)
Local $i = 1
For $j = 2 to $aArray[0]
    If Not StringInStr($aArray[$j], $aArray[$i] & "") Then
        $aArray[$i] &= "]"
        $i += 1
        $aArray[$i] = $aArray[$j]
    Endif
Next
$aArray[$i] &= "]"
$aArray[0] = $i
ReDim $aArray[$i + 1]
_ArrayDisplay($aArray)
Edited by AZJIO
Link to comment
Share on other sites

I guess I shouldn't have tried to avoid using the StringReplace() statements.

#include <Array.au3>
Global $sText = _
'[HKEY_CLASSES_ROOTzzz]' & @CRLF & _
'[HKEY_CLASSES_ROOTzzz.2]' & @CRLF & _
'[HKEY_CLASSES_ROOTzzzky1]' & @CRLF & _
'[HKEY_CLASSES_ROOTzzzky]'
MsgBox(0, "1", $sText)
$sText = StringReplace($sText, "]", "")
Local $aArray = StringSplit($sText , @CRLF, 1)
_ArraySort($aArray, 0, 1)
_ArrayDisplay($aArray)
Local $i = 1
For $j = 2 to $aArray[0]
    If Not StringInStr($aArray[$j], $aArray[$i]) Then
        $aArray[$i] = StringReplace($aArray[$i], "", "]", -1)
        $i += 1
        $aArray[$i] = $aArray[$j]
    Endif
Next
$aArray[$i] = StringReplace($aArray[$i], "", "]", -1)
$aArray[0] = $i
ReDim $aArray[$i + 1]
_ArrayDisplay($aArray)
Link to comment
Share on other sites

Using this $sText test data, your first post example returns "[HKEY_CLASSES_ROOT.wavPersistentHandler]" which I assume is not want you want because "[HKEY_CLASSES_ROOT.wav]" is also returned.

;#include <Array.au3>

Local $sText = _
        '[HKEY_CLASSES_ROOT.wavPersistentHandler]' & @CRLF & _
        '[HKEY_CLASSES_ROOT.wavPersistentHandlerrav]' & @CRLF & _
        '[HKEY_CLASSES_ROOT.wav]' & @CRLF & _
        '[HKEY_CLASSES_ROOTwavfileDefaultIcon]' & @CRLF & _
        "[rndgf]" & @CRLF & _
        '[HKEY_CLASSES_ROOTwavfileshell]' & @CRLF & _
        '[HKEY_CLASSES_ROOTwavfileshellopencommand]'

Local $sTextNew, $iFlag, $aReg

$aReg = StringRegExp($sText, "(?m)^([HK.*?)]", 3)
;_ArrayDisplay($aReg, 'aReg')

For $i = 0 To UBound($aReg) - 1
    $iFlag = 1
    For $j = 0 To UBound($aReg) - 1
        If $i <> $j And StringInStr($aReg[$i], $aReg[$j]) Then
            $iFlag = 0
            ExitLoop
        EndIf
    Next
    If $iFlag Then $sTextNew &= $aReg[$i] & "]" & @CRLF
Next
MsgBox(0, '"2 For-Nexts with StringInStr" Method', $sTextNew)
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...