Jump to content

RegExp - optimize --> ReduceSpaces()


Go to solution Solved by Melba23,

Recommended Posts

Posted (edited)

I have got this simple function for reduction of more than 3 spaces to only two spaces

 

ConsoleWrite(ReduceSpaces(' abc def 1 2 ')& @CRLF)
ConsoleWrite(ReduceSpaces('a b c d e')& @CRLF)
ConsoleWrite(ReduceSpaces('abc')& @CRLF)
ConsoleWrite(ReduceSpaces('')& @CRLF)

; 3 and more spaces reduces to 2 spaces
Func ReduceSpaces($s)
  Return StringRegExpReplace($s, "\x20{3,}", "  ")
EndFunc
 

But I want also more general version of this function where as parameters will be number of spaces.

Here is my function but it's not optimal and I hope it can be done by some more clever RegExp without FOR/NEXT loop.

 

Please some RegExp guru help me increase my RegExp experiencies :-)

 

; N1 and more spaces reduces to N2 spaces
Func ReduceSpaces($s, $n1=3, $n2=2)
    $space2 = ''
    For $i = 1 To $n2
        $space2 &= ' '
    Next
    Return StringRegExpReplace($s, "\x20{"&$n1&",}", $space2)
EndFunc
Edited by Zedna
Posted (edited)

Zedna,

One possible way...

#include <string.au3>

$string = 'abc      def  123         456                                   ' & @crlf & '          mmmm     12'

ConsoleWrite(ReduceSpaces($string,3,2) & @LF)

; N1 and more spaces reduces to N2 spaces
Func ReduceSpaces($s, $n1=3, $n2=2)
    local $spaces = _stringrepeat(' ',$n2)
    Return StringRegExpReplace($s, "\x20{"&$n1&",}", $spaces)
EndFunc

kylomas

edit: hmmm...unintended consequence...it can also expand spaces to whatever you like...

#include <string.au3>

$string = 'abc      def  123         456                                   ' & @crlf & '          mmmm     12'

ConsoleWrite(ReduceSpaces($string,2,40) & @LF)

; N1 and more spaces reduces to N2 spaces
Func ReduceSpaces($s, $n1=3, $n2=2)
    local $spaces = _stringrepeat(' ',$n2)
    Return StringRegExpReplace($s, "\x20{"&$n1&",}", $spaces)
EndFunc
Edited by kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

  • Moderators
  • Solution
Posted (edited)

Zedna,

Try this one:

ConsoleWrite("|" & ReduceSpaces('    abc   def  1 2 ') & "|" & @CRLF)
ConsoleWrite("|" & ReduceSpaces('a           b      c d  e') & "|" & @CRLF)
ConsoleWrite("|" & ReduceSpaces('abc') & "|" & @CRLF)
ConsoleWrite("|" & ReduceSpaces('') & "|" & @CRLF)


Func ReduceSpaces($sString, $iAccept = 4, $iReplace = 2)

    If $iReplace > $iAccept Then
        Return SetError(1, 0, "")
    EndIf

    Return StringRegExpReplace($sString, "(\x20{" & $iReplace & "})\x20{" & $iAccept - $iReplace + 1 & ",}", "$1")

EndFunc
We look for the Replace number of spaces followed by enough spaces to take it over the Accept limit - if found we replace them all by the Replace number of spaces - which we captured when searching.  Obviously you need to accept at least the same number as you expect to replace - hence the check. ;)

It works for me when I play around with the different values. :)

 

M23

Edited by Melba23
Better explanation - I hope

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

  Reveal hidden contents

 

  • Moderators
Posted

Zedna,

 

  Quote

Nice view on problem from different angle

Edward de Bono was always one of my heroes. ;)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

  Reveal hidden contents

 

Posted (edited)

Zedna,

  Quote

@kylomas
_stringrepeat does the same FOR/NEXT loop internally as my original (not optimal) version

 

Yes, just thought I would offer it...should have known that you already considered it...

Speedy recovery by the way!

kylomas

editL spelling

Edited by kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Posted

I did testing of Melba's solution and there was bug:
Instead of $iAccept - $iReplace + 1
should be $iAccept - $iReplace

I also changed behaviour at error state, when error occurs (bad parametres) then original (not empty) string returned.

So here is final version
 

ConsoleWrite("|" & ReduceSpaces('    abc   def  1 2     3 ',5,2) & "|" & @CRLF)
ConsoleWrite("|" & ReduceSpaces('    abc   def  1 2     3 ',4,2) & "|" & @CRLF)
ConsoleWrite("|" & ReduceSpaces('    abc   def  1 2     3 ',3,2) & "|" & @CRLF)
ConsoleWrite("|" & ReduceSpaces('a           b      c d  e') & "|" & @CRLF)
ConsoleWrite("|" & ReduceSpaces('abc') & "|" & @CRLF)
ConsoleWrite("|" & ReduceSpaces('') & "|" & @CRLF)

Func ReduceSpaces($sString, $iAccept = 3, $iReplace = 2)
    If $iReplace > $iAccept Then Return SetError(1, 0, $sString)

    Return StringRegExpReplace($sString, "(\x20{" & $iReplace & "})\x20{" & $iAccept - $iReplace & ",}", "$1")
EndFunc

Thanks

  • Moderators
Posted

Zedna,

Sorry, I misunderstood the limit for change - I am glad you were able to fix it. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

  Reveal hidden contents

 

Posted

  On 5/28/2013 at 2:21 PM, Zedna said:

@kylomas

_stringrepeat does the same FOR/NEXT loop internally as my original (not optimal) version

Not in the AutoIt beta, this is a lot more optimisied.

UDF List:

  Reveal hidden contents

Updated: 22/04/2018

Posted
  On 5/29/2013 at 4:56 AM, guinness said:

Not in the AutoIt beta, this is a lot more optimisied.

 

Thanks for info I will look at it.

I'm old school guy.

I use 3.2.12.1 as my release a 3.3.7.23 as my latest beta.

It's due to many script breaking changes and many my live big projects

(the most compatible with 3.2.12.1 and few compatible with 3.3.7.x)

where I would make changes and testing to follow these script breaking changes from newer release/beta versions.

So I don't  have installed newer release/beta on my computer, 

I look at changes in changelogs and and download only ZIP packages of newer release/beta to look at it.

I would be happy to have possibility to install/use more AutoIt/Scite4AutoIt3 versions into different folders at the same time

so I could compile all my older projects with older AutoIt

and I could use latest release/beta for new projects.

Unfortunatelly it's not possible as far as I know :-(

If there is some trick how to do it, please share it with me, thanks.

Posted

This is the beta version of _StringRepeat >> #2172 (the while loop is the most important and doesn't reflect the version in the beta.)

What about using AutoItWrapper to change the AutoIt install path e.g.

#AutoIt3Wrapper_Autoit3Dir=                     ;Optionally override the base AutoIt3 install directory.
#AutoIt3Wrapper_Aut2exe=                        ;Optionally override the Aut2exe.exe to use for this script
#AutoIt3Wrapper_AutoIt3=                        ;Optionally override the Autoit3.exe to use for this script

Source: http://www.autoitscript.com/autoit3/scite/docs/directives.html

UDF List:

  Reveal hidden contents

Updated: 22/04/2018

Posted (edited)
  On 5/29/2013 at 8:06 AM, guinness said:

What about using AutoItWrapper to change the AutoIt install path e.g.

#AutoIt3Wrapper_Autoit3Dir=                     ;Optionally override the base AutoIt3 install directory.
#AutoIt3Wrapper_Aut2exe=                        ;Optionally override the Aut2exe.exe to use for this script
#AutoIt3Wrapper_AutoIt3=                        ;Optionally override the Autoit3.exe to use for this script

Source: http://www.autoitscript.com/autoit3/scite/docs/directives.html

As far as I know there is problem with standard include files.

If I manually copy new beta (from sfx or zip) to some nonstandard folder and use these directives, include folder is still not changed (?).

Edited by Zedna
Posted

I honestly don't know as I've always had a stable version and beta version. But it seems you want more than 2 installations of AutoIt.

_StringRepeat: v3.3.9.5+

; #FUNCTION# ====================================================================================================================
; Name ..........: _StringRepeat
; Description ...: Repeats a string a specified number of times.
; Syntax.........: _StringRepeat ( $sString, $iRepeatCount )
; Parameters ....: $sString             - String to repeat
;                  $iRepeatCount        - Number of times to repeat the string
; Return values .: Success - Returns string with specified number of repeats
;                  Failure - Returns an empty string and sets @error = 1
;                  |@error  - 0 = No error.
;                  |@error  - 1 = One of the parameters is invalid
; Author ........: Jeremy Landes <jlandes at landeserve dot com>
; Modified.......: guinness - Removed Select...EndSelect statement and replaced with an If...EndIf as well as optimised the code.
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _StringRepeat($sString, $iRepeatCount)
    ; Casting Int() takes care of String/Int, Numbers.
    $iRepeatCount = Int($iRepeatCount)
    ; Zero is a valid repeat integer.
    If StringLen($sString) < 1 Or $iRepeatCount < 0 Then Return SetError(1, 0, "")
    Local $sResult = ""
    While $iRepeatCount > 1
        If BitAND($iRepeatCount, 1) Then $sResult &= $sString
        $sString &= $sString
        $iRepeatCount = BitShift($iRepeatCount, 1)
    WEnd
    Return $sString & $sResult
EndFunc   ;==>_StringRepeat

UDF List:

  Reveal hidden contents

Updated: 22/04/2018

  • 1 year later...
Posted (edited)
  On 5/29/2013 at 7:58 AM, Zedna said:
I use 3.2.12.1 as my release a 3.3.7.23 as my latest beta.

 

It's due to many script breaking changes and many my live big projects

(the most compatible with 3.2.12.1 and few compatible with 3.3.7.x)

where I would make changes and testing to follow these script breaking changes from newer release/beta versions.

So I don't  have installed newer release/beta on my computer, 

I would be happy to have possibility to install/use more AutoIt/Scite4AutoIt3 versions into different folders at the same time

so I could compile all my older projects with older AutoIt

and I could use latest release/beta for new projects.

Unfortunatelly it's not possible as far as I know 😞

If there is some trick how to do it, please share it with me, thanks.

Expand  

 

Just for the reference:

My solution is as follows:

I unpacked latest release+beta+Scite4AutoIt3 from ZIP packages to different directory: "C:\Program Files\AutoIt3312"

https://www.autoitscript.com/autoit3/files/archive/autoit/

In "C:\Program Files\AutoIt3" I have got installed my main 3.2.12.1+3.3.7.23+old scite4autoit3

AU3 scripts are opened/ran/compiled in my default 3.2.12.1 editor+autoit+compiler by default (when opened from file manager by Enter or doubleclick).

When I need to open/run/compile AU3 in latest release/beta then I open it in new scite4autoit3 from Total Commander by Start menu:

 

  Quote

title: AU3 3.3.12.0

command: C:\Program Files\AutoIt3312\SciTe\SciTE.exe

param: %p%n

dir: %p

 

Expand  
Edited by Zedna
added striped backslashes in paths

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
  • Recently Browsing   0 members

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