Jump to content

StringRegExp problem


Recommended Posts

I have created the following function, that:

- check in a xml file if there are lines with "$Drive" string

- for lines that contain this string, the function substitute it with the drive letter

- then if the line contains "PathExe" or "PathIcon" it extract the absolute path present in the line and substitute it with a relative path

Func FixPath()
    Local $line, $oldline, $let, $array[1], $path
    
    $let = StringLeft(@ScriptDir, 2)
    $input = FileOpen($xml, 0)
    $output = FileOpen($temp, 2)
    While 1
        $line = FileReadLine($input)
        If @Error = -1 Then ExitLoop
        If StringInStr($line, "$Drive") Then
            $oldline = $line
            $line = StringReplace($line, "$Drive", $let)
            If StringInStr($line, "PathExe") Then
                $array = StringRegExp($line, '<(?i)Path(?i)Exe>(.*?)</(?i)Path(?i)Exe>', 3)
                If @Error = -1 Then
                    $line = $oldline
                Else
                    $path = _PathGetRelative($suite, $array[0])
                    $path = StringTrimLeft($path, 3)
                    $path = StringReplace($path, "\", "<xx>")
                    $line = StringRegExpReplace($line, '<(?i)Path(?i)Exe>(.*?)</(?i)Path(?i)Exe>', '<PathExe>' & $path & '</PathExe>')
                EndIf
            Else
                $array = StringRegExp($line, '<(?i)Path(?i)Icon>(.*?)</(?i)Path(?i)Icon>', 3)
                If @Error = -1 Then
                    $line = $oldline
                Else
                    $path = _PathGetRelative($suite, $array[0])
                    $path = StringTrimLeft($path, 3)
                    $path = StringReplace($path, "\", "<xx>")
                    $line = StringRegExpReplace($line, '<(?i)Path(?i)Icon>(.*?)</(?i)Path(?i)Icon>', '<PathIcon>' & $path & '</PathIcon>')
                EndIf
            EndIf
            $line = StringReplace($line, "<xx>", "\")
        EndIf
        FileWriteLine($output, $line)
    WEnd
    FileClose($input)
    FileClose($output)
    FileCopy($temp, $xml, 1)
    FileDelete($temp)
EndFunc

("$suite" is a given path)

I need to improve the code of the function (I think the procedure that I have created could be improved..also because I use a strange mode to replease "\" character, if someone can help me to to it better).

Secondly, in some cases (I can't understand when), the compiled script doesn't work and appear an error that says "Array variable has incorrect number of subscripts or subscript dimension range exeeded."

Can someone help me? Thanks!

SFTPEx, AutoCompleteInput_DateTimeStandard(), _ImageWriteResize()_GUIGraduallyHide(): some AutoIt functions.

Lupo PenSuite: all-in-one and completely free selection of portable programs and games.

DropIt: a personal assistant to automatically manage your files.

ArcThemALL!: application to multi-archive your files and folders.

Link to comment
Share on other sites

I think that if StringRegExp with option 3 fails to match the error is sets to 1 rather than -1. It'd be much simpler just to check if the return value is an array using IsArray. Also you don't need to put (?i) on every word to imply case-insensitive match, just put it in the front of the regexp and that's it.

Can you give an example of a few lines so it's possible to work with something to see how it's look like?

Link to comment
Share on other sites

This is an example of some lines:

<Category name="Internet">
      <PathIcon>Icons\Set\11.ico</PathIcon>
      <Category name="Web Browsers">
        <PathIcon>Icons\Set\folder.ico</PathIcon>
        <Software name="Firefox Plus">
          <PathCache>cache\1.ico</PathCache>
          <PathExe>$Drive\Suite\Apps\Firefox Plus\FirefoxPortable.exe</PathExe>
        </Software>
        <Software name="OperaPortable">
          <PathCache>cache\2.ico</PathCache>
          <PathExe>..\Apps\OperaPortable\OperaPortable.exe</PathExe>
        </Software>
      </Category>
      <Category name="E-Mail Clients">
        <PathIcon>Icons\Set\folder.ico</PathIcon>
        <Software name="Thunderbird Plus">
          <PathCache>cache\3.ico</PathCache>
          <PathExe>..\Apps\Thunderbird Plus\ThunderbirdPortable.exe</PathExe>
        </Software>
        <Software name="POP Peeper">
          <PathCache>cache\4.ico</PathCache>
          <PathExe>..\Apps\POP Peeper\POPPeeper.exe</PathExe>
        </Software>
      </Category>

The function detect the line that include "$Drive" string and substitute it with the corresponding relative path (this $Drive string is used by the software as the drive letter).

I have added the If @Error = -1 Then checking to try to fix the error, I know it could not work fine. I don't understand how the StringRegExp function work, so I can't use it in the correct way.

I also need to correctly manage paths in the function, instead of using the substitution of the character "\" with "<xx>" during the procedure (otherwise the function doesn't work fine, and \ characters are not kept).

SFTPEx, AutoCompleteInput_DateTimeStandard(), _ImageWriteResize()_GUIGraduallyHide(): some AutoIt functions.

Lupo PenSuite: all-in-one and completely free selection of portable programs and games.

DropIt: a personal assistant to automatically manage your files.

ArcThemALL!: application to multi-archive your files and folders.

Link to comment
Share on other sites

Some of the things I couldn't really relate to I've left commented. The function's main task didn't change, only clarity and variables name get changed:

#include <File.au3>
            
Dim $sFile = @ScriptDir & '\test.xml', $sFileTemp = @ScriptDir & '\Test.Temp.xml'
FixPath($sFile, $sFileTemp)


Func FixPath($sXML, $sTemp)
    Local $sLine, $sOldLine, $sLet, $array, $sPath
    Local $sSuite = @ScriptDir & '\..' ; For testing purpose.
    
    $sLet = StringLeft(@ScriptDir, 2)
    $hInput = FileOpen($sXML, 0)
    $hOutput = FileOpen($sTemp, 2)
    
    While 1
        $sLine = FileReadLine($hInput)
        If @Error = -1 Then ExitLoop
        
        If StringInStr($sLine, "$Drive") Then
            $sOldLine = $sLine
            $sLine = StringReplace($sLine, "$Drive", $sLet)
            
            If StringInStr($sLine, "pathexe") Then
                $array = StringRegExp($sLine, '(?i)<pathexe>(.*?)</pathexe>', 1)
                If Not IsArray($array) Then
                    $sLine = $sOldLine
                Else
                    $sPath = _PathGetRelative($sSuite, $array[0])
                    $sPath = StringTrimLeft($sPath, 3)
                    $sPath = StringReplace($sPath, "\", "<xx>")
                    $sLine = StringRegExpReplace($sLine, '(?i)<pathexe>.*?</pathexe>', '<PathExe>' & $sPath & '</PathExe>')
                EndIf
            Else
                $array = StringRegExp($sLine, '(?i)<pathicon>(.*?)</pathicon>', 1)
                If Not IsArray($array) Then
                    $sLine = $sOldLine
                Else
                    $sPath = _PathGetRelative($sSuite, $array[0])
                    $sPath = StringTrimLeft($sPath, 3)
                    $sPath = StringReplace($sPath, "\", "<xx>")
                    $sLine = StringRegExpReplace($sLine, '(?i)<pathicon>.*?</pathicon>', '<PathIcon>' & $sPath & '</PathIcon>')
                EndIf
            EndIf
            $sLine = StringReplace($sLine, "<xx>", "\")
        EndIf
        FileWriteLine($hOutput, $sLine)
    WEnd
    FileClose($hInput)
    FileClose($hOutput)
    ;FileCopy($sTemp, $sXML, 1) 
    ;FileDelete($sTemp)
EndFunc

I've tested and the "relative" path was written correctly, the tags and the paths was visually correct but I couldn't test it.

Link to comment
Share on other sites

Good, now I try to implement it.. but why the last two lines are commented?

;FileCopy($sTemp, $sXML, 1)
;FileDelete($sTemp)

ps: why in StringRegExp you use (.*?) and in StringRegExpReplace only .*? ?

Edited by Lupo73

SFTPEx, AutoCompleteInput_DateTimeStandard(), _ImageWriteResize()_GUIGraduallyHide(): some AutoIt functions.

Lupo PenSuite: all-in-one and completely free selection of portable programs and games.

DropIt: a personal assistant to automatically manage your files.

ArcThemALL!: application to multi-archive your files and folders.

Link to comment
Share on other sites

Because there is no reference to any captured parentheses, you just change anything between the opening (including) <pathexe> and the closing </pathexe> and replace it by <pathexe> & $sPath & </pathexe>. Same is with <pathicon>.

Capturing parentheses without referencing them (specifically in StringRegExpReplace) is pointless because the things that take place in the match are replaced as well.

You could do this but it's stupid example:

$sStr = StringRegExpReplace($sStr, '(<pathexe>).*?(</pathexe>)', '${1}' & $sPath & '\2')

I've commented those 2 lines because I've had no use for them when I tested the function to see if it works.

Link to comment
Share on other sites

Good, it seem to work fine..thanks :P

SFTPEx, AutoCompleteInput_DateTimeStandard(), _ImageWriteResize()_GUIGraduallyHide(): some AutoIt functions.

Lupo PenSuite: all-in-one and completely free selection of portable programs and games.

DropIt: a personal assistant to automatically manage your files.

ArcThemALL!: application to multi-archive your files and folders.

Link to comment
Share on other sites

  • 2 weeks later...

I have a problem again with this code. It may be a bug in File library:

Posted Image

Func FixPath()
    Local $sLine, $sOldLine, $sLet, $array, $sPath
   
    $sLet = StringLeft(@ScriptDir, 2)
    $input = FileOpen($xml, 0)
    $output = FileOpen($temp, 2)
   
    While 1
        $sLine = FileReadLine($input)
        If @Error = -1 Then ExitLoop
       
        If StringInStr($sLine, "$Drive") Then
            $sOldLine = $sLine
            $sLine = StringReplace($sLine, "$Drive", $sLet)
           
            If StringInStr($sLine, "pathexe") Then
                $array = StringRegExp($sLine, '(?i)<pathexe>(.*?)</pathexe>', 1)
                If Not IsArray($array) Then
                    $sLine = $sOldLine
                Else
                    $sPath = _PathGetRelative($suite, $array[0])
                    $sPath = StringTrimLeft($sPath, 3)
                    $sPath = StringReplace($sPath, "\", "<xx>")
                    $sLine = StringRegExpReplace($sLine, '(?i)<pathexe>.*?</pathexe>', '<PathExe>' & $sPath & '</PathExe>')
                EndIf
            Else
                $array = StringRegExp($sLine, '(?i)<pathicon>(.*?)</pathicon>', 1)
                If Not IsArray($array) Then
                    $sLine = $sOldLine
                Else
                    $sPath = _PathGetRelative($suite, $array[0])
                    $sPath = StringTrimLeft($sPath, 3)
                    $sPath = StringReplace($sPath, "\", "<xx>")
                    $sLine = StringRegExpReplace($sLine, '(?i)<pathicon>.*?</pathicon>', '<PathIcon>' & $sPath & '</PathIcon>')
                EndIf
            EndIf
            $sLine = StringReplace($sLine, "<xx>", "\")
        EndIf
        FileWriteLine($output, $sLine)
    WEnd
    FileClose($input)
    FileClose($output)
    FileCopy($temp, $xml, 1)
    FileDelete($temp)
EndFunc

SFTPEx, AutoCompleteInput_DateTimeStandard(), _ImageWriteResize()_GUIGraduallyHide(): some AutoIt functions.

Lupo PenSuite: all-in-one and completely free selection of portable programs and games.

DropIt: a personal assistant to automatically manage your files.

ArcThemALL!: application to multi-archive your files and folders.

Link to comment
Share on other sites

Otherwise someone know a way to bypass the problem or an alternative function from "_PathGetRelative"? thanks!

Edited by Lupo73

SFTPEx, AutoCompleteInput_DateTimeStandard(), _ImageWriteResize()_GUIGraduallyHide(): some AutoIt functions.

Lupo PenSuite: all-in-one and completely free selection of portable programs and games.

DropIt: a personal assistant to automatically manage your files.

ArcThemALL!: application to multi-archive your files and folders.

Link to comment
Share on other sites

I have a problem again with this code. It may be a bug in File library:

Posted Image

CODE
Func FixPath()

Local $sLine, $sOldLine, $sLet, $array, $sPath

$sLet = StringLeft(@ScriptDir, 2)

$input = FileOpen($xml, 0)

$output = FileOpen($temp, 2)

While 1

$sLine = FileReadLine($input)

If @Error = -1 Then ExitLoop

If StringInStr($sLine, "$Drive") Then

$sOldLine = $sLine

$sLine = StringReplace($sLine, "$Drive", $sLet)

If StringInStr($sLine, "pathexe") Then

$array = StringRegExp($sLine, '(?i)<pathexe>(.*?)</pathexe>', 1)

If Not IsArray($array) Then

$sLine = $sOldLine

Else

$sPath = _PathGetRelative($suite, $array[0])

$sPath = StringTrimLeft($sPath, 3)

$sPath = StringReplace($sPath, "\", "<xx>")

$sLine = StringRegExpReplace($sLine, '(?i)<pathexe>.*?</pathexe>', '<PathExe>' & $sPath & '</PathExe>')

EndIf

Else

$array = StringRegExp($sLine, '(?i)<pathicon>(.*?)</pathicon>', 1)

If Not IsArray($array) Then

$sLine = $sOldLine

Else

$sPath = _PathGetRelative($suite, $array[0])

$sPath = StringTrimLeft($sPath, 3)

$sPath = StringReplace($sPath, "\", "<xx>")

$sLine = StringRegExpReplace($sLine, '(?i)<pathicon>.*?</pathicon>', '<PathIcon>' & $sPath & '</PathIcon>')

EndIf

EndIf

$sLine = StringReplace($sLine, "<xx>", "\")

EndIf

FileWriteLine($output, $sLine)

WEnd

FileClose($input)

FileClose($output)

FileCopy($temp, $xml, 1)

FileDelete($temp)

EndFunc

What are the values of the $suite and $array[0] inputs to _PathGetRelative() when it fails? Maybe you should just check the $array[0] value for validity before passing it to _PathGetRelative.

:D

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

They may be paths, but how can I check them before? I don't know what features need to have to work fine..

SFTPEx, AutoCompleteInput_DateTimeStandard(), _ImageWriteResize()_GUIGraduallyHide(): some AutoIt functions.

Lupo PenSuite: all-in-one and completely free selection of portable programs and games.

DropIt: a personal assistant to automatically manage your files.

ArcThemALL!: application to multi-archive your files and folders.

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...