Sign in to follow this  
Followers 0
AZJIO

Remove nested strings

16 posts in this topic

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

Share this post


Link to post
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.

Share this post


Link to post
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)

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

Share this post


Link to post
Share on other sites

boththose

With 1000 lines of your script runs slower in 3 times. 4.56 vs. 1.64

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

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

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Thank you

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

Why not export a single line?

[HKEY_CLASSES_ROOT]
I will need to export from the registry. The smaller the better. Export the registry root is too much data Edited by AZJIO

Share this post


Link to post
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?


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

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

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

Share this post


Link to post
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.

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

Spiff59

If not, I guess a pre-sort would be needed.

Sorting requires a lot of time. I'm testing.

I wanted to optimize this script - reg-backup

So before importing new settings from the reg-file, export your current settings.

Edited by AZJIO

Share this post


Link to post
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)

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

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

Share this post


Link to post
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)

Share this post


Link to post
Share on other sites

You're basically looking for a minimum spanning tree, right?

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

Spiff59

Thank you. Now 1000 rows without errors.

The previous script processed 3700 lines within 13 minutes. Now 2 seconds. Link to the script, I indicated above

Edited by AZJIO

Share this post


Link to post
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)

Share this post


Link to post
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
Sign in to follow this  
Followers 0