Jump to content

RegExp poser


Recommended Posts

I need to detect a placeholder in a file, when the file could be munged by a MIME encoder.

I.e. I need to detect the instance of a the placeholder string "$VAR" where the value in the text could be:

"$VAR"  ;trivial

;placeholder at end of line with @CRLF (windows encoders)
;or just @LF or @CR ( *nix and macintosh encoders)
"$" & '=' & @CR & @LF & "VAR"
"$V" & '=' & @CR & @LF & "AR"
"$VA" & '=' & @CR & @LF & "R"

i'm not sure how or if to escape the "$" symbol.

I think that the \s to match whitespace could very well be useful, but I can't

seem to figure out how to with one command handle the varying location of the '='.

Suggestions welcome.

Reading the help file before you post... Not only will it make you look smarter, it will make you smarter.

Link to comment
Share on other sites

  • Moderators

I must say I am a tad confused with what you've written.

Rather than guessing (and more than likely be mistaken), could you tell me exactly what you hope to return from the string you provided?

ie:

$aArray[0] = "?"

$aArray[1] = "??"

etc...

Edit:

Here, I'll take a stab at what I understand it to be:

#include <array.au3>
$sString = "$" & '=' & @CR & @LF & "VAR" & _
                "$V" & '=' & @CR & @LF & "AR" & _
                "$VA" & '=' & @CR & @LF & "R"

$aArray = StringRegExp($sString, "(?s)(?i)\$.*?=\r\n(\w+)|\$.*=\r(\w+)|\$.*=\n(\w+)", 3)
_ArrayDisplay($aArray)
Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Thanks for looking at the issue. Here is another attempt to explain myself :)

GIVEN: a string variable of varying length $haystack wherein exists

one and only one substring "%NEEDLE%"

$haystack = "foo%NEEDLE%bar"

Due to the nature of the haystack, the NEEDLE may not be intact.

$haystack = "foo%NEE=" & @CRLF & "DLE%" & "bar"
;or
$haystack = "foo%=" & @LF & "NEEDLE%" & "bar"

There will always be an equals sign "=" and usuallysome form of whitespace, [@CR|@LF|@CRLF] breaking up the needle.

I am attempting to find a regexp pattern that will enable me to find the needle in $haystack, no matter how the needle can be broken.

Edit: Realized the $ symbol in the placeholder could be confusing, changed $NEEDLE to %NEEDLE% to clarify.

Edited by flyingboz

Reading the help file before you post... Not only will it make you look smarter, it will make you smarter.

Link to comment
Share on other sites

  • Moderators

Do you know the Needle name ahead of time? Is it literally encased in a percent sign? I understand what you are trying to do now, but the explination by story it really confusing.

1. Do you know what string you want to find (despite how it can be split up)?

2. Do you only want to know if that string exist?

3. You say instance, are you trying to find out it's string position (I assume this because you stated something about inserting something)?

4. Do you need a return value of any sort or if I'm right in #3 do you just need the string position to start?

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • Moderators

I thought there was a string position match option with StringRegxp() but I couldn't find it... :)

Anyway, if that is what you are trying to do (what I stated in previous post):

;@CR = \r
;@LF = \n
;% = escape with \

$sString = "foo%=" & @LF & "NEE" & @CR & "DLE%" & "bar"
$sVar = 'needle'
$sPat = _FindPos($sString, $sVar)
MsgBox(0,"Position","First Matched Position = " & $sPat)
Func _FindPos($sString, $sFind)
    Local $sPattern = '\%(', $sMid
    Local $nLen = StringLen($sFind)
    For $iCC = 1 To $nLen
        $sMid = StringMid($sFind, $iCC, 1)
        $sPattern &= '[=\r\n' & $sMid & ']+'
    Next
    $sPattern &= ')\%'
    Local $aSRE = StringRegExp($sString, "(?s)(?i)" & $sPattern, 1)
    If IsArray($aSRE) Then Return StringInStr($sString, $aSRE[0])
    Return SetError(1, 0, -1)
EndFunc

That will return 5 (as the start of the match) you can add -1,-2,-3 or whatever to it to get the posiiton for inputing your other information.

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

@SmOke_N,

Thanks for taking a stab at it. I certainly learned a few things about au3's regexp implementation / usage by looking at your posts.

Well above and beyond the call of duty.

Unfortunately, if I have to iterate, I'll just iteratively break the needle into two pieces and search through the possibilities. Will likely be easier for me to debug / modify down the line. I was thinking that a one-liner (non-looping) regexp would dramatically improve performance on large files, though.

This is the code I wrote to iterate through the possibilities...It can (hopefully) show clearer than my words

what I am trying to accomplish.

I am sure that there is some way to create a regexp that will handle the problem too, I just don't know

(a) what it is, and (:) whether autoit's implementation would support it.

Func _MimeReplaceValue(ByRef $haystack, $needle, $new)
                ;func preserves encoded EOL chars (@CR/@LF)
                ;on success replaces $needle with $new
                ;on failure (can't find needle) sets @error = 1
    Local $left, $pos_left
    Local $right, $pos_right
    Select
        Case StringInStr($haystack, $needle)
            $haystack = StringReplace($haystack, $needle, $new)
                                 Return
        Case Else
            ;the parameter is missing or munged up.
            For $i = 1 To StringLen($needle)
                $left = StringLeft($needle, $i) & '=' 
                $right = StringTrimLeft($needle, $i)
                $pos_left = StringInStr($haystack, $left)
                $pos_right = StringInStr($haystack, $right)
                If $pos_left < $pos_right And $pos_left > 0 Then
                    $haystack = StringReplace($haystack, $left, StringLeft($new, $i) & '=')
                    $haystack = StringReplace($haystack, $right, StringTrimLeft($new, $i))
                    Return
                EndIf
            Next
            ;didn't find placeholder in file.
            Return SetError(1, 0, '')
    EndSelect
    
EndFunc
Edited by flyingboz

Reading the help file before you post... Not only will it make you look smarter, it will make you smarter.

Link to comment
Share on other sites

  • Moderators

I only looped the string to find to set up the search pattern. That will only be a "few" chars.

Your example demonstrates a similar method, but you are searching the entire file as many times as there are characters in the search string.

I'm sure there is a better method than what I've shown, but it escapes me if there is at the moment. If it comes to mind throughout the day, I'll post back.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

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