Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Put here requests of problems with regular expressions


  • Please log in to reply
1074 replies to this topic
PhiLho
  • Moderators
  • 6850 posts
  • Last active: Jan 02 2012 10:09 PM
  • Joined: 27 Dec 2005
The solutions will be posted here, and if of generic interest, collected in another topic which you should check to see if your problem isn't already solved. Check out also the Regular Expression Library for a comprehensive list of such expressions.
Posted Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")

SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005
How to remove a character that should not exist in beginning/end of string?

Here is a classic example:

Loop %A_Windir%\*.bmp
  BMPFiles = %BMPFiles%`n%A_LoopFileName%

StringTrimLeft, BMPFiles, BMPFiles, 1
MsgBox, % BMPFiles

In the above example I know that the linefeed will definitely occur as the first character in the built-up string, thus StringTrimLeft is a solution.

I need a one line solution of RegExReplace that would check the Beginning/End of string for a match character and remove it if present.

Something that might take many lines as in TrimPipe() :
MsgBox % TrimPipe("Apples|Bananas|Cherries")
MsgBox % TrimPipe("|Apples|Bananas|Cherries")
MsgBox % TrimPipe("Apples|Bananas|Cherries|")
MsgBox % TrimPipe("|Apples|Bananas|Cherries|")

TrimPipe(Str) {
StringLeft, L, Str, 1
IfEqual,L,|, StringTrimLeft, Str,Str,1
StringRight, R, Str, 1
IfEqual,R,|, StringTrimRight, Str,Str,1
Return Str
}

I require this for string validation in my CreateArray() function.

Solution:

String1 := "Apples|Bananas|Cherries"
String2 := "|Apples|Bananas|Cherries"
String3 := "Apples|Bananas|Cherries|"
String4 := "|Apples|Bananas|Cherries|"

Loop 4,
  MsgBox % RegExReplace( String%A_Index%, "^\|?(.*?)\|?$", "$1")

Thanks to Titan & PhiLho :)
kWo4Lk1.png

polyethene
  • Members
  • 5519 posts
  • Last active: May 17 2015 06:39 AM
  • Joined: 26 Oct 2012

I need a one line solution of RegExReplace that would check the Beginning/End of string for a match character and remove it if present.

The pipe char needs to be escaped so: MsgBox % RegExReplace("|Apples|Bananas|Cherries|", "^\|?(.*)\|+$", "$1")
Try removing the first and/or last pipe chars, it still works.

PhiLho, I apologize if you wanted to be the only supporter here.

autohotkey.com/net Site Manager

 

Contact me by email (polyethene at autohotkey.net) or message tidbit


SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005
Dear Titan, :)

The third one fails .. Should be a small tweak, which I am not able to guess.
MsgBox % RegExReplace("|Apples|Bananas|Cherries|", "^\|?(.*)\|+$", "$1") 
MsgBox % RegExReplace("Apples|Bananas|Cherries|" , "^\|?(.*)\|+$", "$1")
[color=red]MsgBox % RegExReplace("|Apples|Bananas|Cherries" , "^\|?(.*)\|+$", "$1")[/color]
MsgBox % RegExReplace("Apples|Bananas|Cherries"  , "^\|?(.*)\|+$", "$1")

Regards, :)
kWo4Lk1.png

polyethene
  • Members
  • 5519 posts
  • Last active: May 17 2015 06:39 AM
  • Joined: 26 Oct 2012
Sorry my regex wasn't thorough enough, this works: ^\|*(.*[^\|])\|*$

autohotkey.com/net Site Manager

 

Contact me by email (polyethene at autohotkey.net) or message tidbit


SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005
Thanks Titan, it works! :D
How do I use a `n ( linefeed) instead of a pipe? :roll:
kWo4Lk1.png

polyethene
  • Members
  • 5519 posts
  • Last active: May 17 2015 06:39 AM
  • Joined: 26 Oct 2012

How do I use a `n ( linefeed) instead of a pipe?

The linefeed is also a control character so you just need to replace \| with \n and use the 'm' (multiline) option: MsgBox, % RegExReplace("`nApples`nBananas`nCherries`n`n", "^\n*(.*[^\n])\n*$", "$1", "m")

autohotkey.com/net Site Manager

 

Contact me by email (polyethene at autohotkey.net) or message tidbit


SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

The linefeed is also a control character so you just need to replace \| with \n and use the 'm' (multiline) option


I am learning! Thanks.. :D
kWo4Lk1.png

polyethene
  • Members
  • 5519 posts
  • Last active: May 17 2015 06:39 AM
  • Joined: 26 Oct 2012

I am learning!

regular-expressions.info is a great place to start.

autohotkey.com/net Site Manager

 

Contact me by email (polyethene at autohotkey.net) or message tidbit


SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

regular-expressions.info is a great place to start.


Thanks for the link. I have been peeking into every link that I find pointing to RegEx tutorials. But, I am one of those commoners who find RegEx encryptic.

Learning by examples: IMHO, Dozens of examples are required before a commoner can take a shot at the tutorial. Examples will also help one to understand how RegEx can simplify string manipulation tasks that might otherwise consume many lines.

If I want to learn RegEx without examples I could do it! But that is not the case with everyone. I highly appreciate PhiLho for opening such a topic.

I wish that this topic grows and gets rich with information that anybody can just copy/paste readymade solutions! They will have the apt to learn once they start using RegEx!
kWo4Lk1.png

PhiLho
  • Moderators
  • 6850 posts
  • Last active: Jan 02 2012 10:09 PM
  • Joined: 27 Dec 2005

PhiLho, I apologize if you wanted to be the only supporter here.

Certainly not! I am not the only one knowing REs, fortunately, so any contribution is welcome!
Posted Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")

SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005
How to remove leading spaces, trailing spaces, or both from a string?

With AutoTrim, On ( which is the default setting ),
Variable = %Variable% will remove both the leading spaces as well as the trailing spaces.

I need three seperate one-line RegExReplace solutions that shall

AllTrim : Remove leading spaces, trailing spaces
LTrim: Remove only leading spaces
RTrim: Remove only trailing spaces

:?:

Solution:
String := "     The Quick Brown Fox     " 

StringA := RegExReplace(String, "(^\s*|\s*$)")
MsgBox,0, AllTrim, % "[" StringA "]"

StringL := RegExReplace(String, "^\s*")        
MsgBox,0, LTrim, % "[" StringL "]"

StringR := RegExReplace(String, "\s*$")
MsgBox,0, RTrim, % "[" StringR "]"

Thanks to PhiLho & majkinetor :)
kWo4Lk1.png

majkinetor
  • Moderators
  • 4512 posts
  • Last active: Jul 29 2016 12:40 AM
  • Joined: 24 May 2006
1.s ^([ \t]*)(.+)([ \t]*)$
1.r \2


2.s ^([ \t]*)(.+)
2.r \2


3.s (.+)([ \t]*)$
3.r \1
Posted Image

SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005
Dear majkinetor, :)

I do not understand it ...

String := "     The Quick Brown Fox     "
MsgBox, % RegExReplace(String, ... ) ; AllTrim
MsgBox, % RegExReplace(String, ... ) ; LTrim
MsgBox, % RegExReplace(String, ... ) ; RTrim

Can you kindly fill in the above example from which I can test it?

Please...
kWo4Lk1.png

PhiLho
  • Moderators
  • 6850 posts
  • Last active: Jan 02 2012 10:09 PM
  • Joined: 27 Dec 2005
Here is my take at Goyyah's first request, I end with something close of the first solution given by Titan for the pipe, but I use something else that I thought would be cool to introduce, bound assertions for start and end of string in a multiline string.
MsgBox %
( Join
 TrimChar("|Apples|Bananas|Cherries|", "\|") . "`n" .
 TrimChar("Apples|Bananas|Cherries|", "\|") . "`n" .
 TrimChar("|Apples|Bananas|Cherries", "\|") . "`n" .
 TrimChar("Apples|Bananas|Cherries", "\|")
)
MsgBox %
( Join
 ">" .
 TrimNewline("`nApples`nBananas`nCherries`n") . "<`n>" .
 TrimNewline("Apples`nBananas`nCherries`n") . "<`n>" .
 TrimNewline("`nApples`nBananas`nCherries") . "<`n>" .
 TrimNewline("Apples`nBananas`nCherries") . "<"
)

TrimChar(_string, _char)
{
	Return RegExReplace(_string
			, "^" . _char . "?(.*?)" . _char . "?$"
			, "$1")
}

TrimNewline(_string)
{
	Return RegExReplace(_string
			, "\A\n?(.*?)\n?\z"
			, "$1", "ms") ; Multiline, DotAll
}
As shown, if the char is a RE special char, it must be escaped.

Unlike Titan, I remove only one char, ie. if the string ends as "foo|||", you will get "foo||". That can be what you want or not.
If you want to trim out all chars, just replace the ? after the char to remove with a *.
TrimChars(_string, _char)
{
	Return RegExReplace(_string
			, "^" . _char . "*(.*?)" . _char . "*$"
			, "$1")
}

TrimNewlines(_string)
{
	Return RegExReplace(_string
			, "\A\n*(.*?)\n*\z"
			, "$1", "ms")
}
Also note that you can write either \n or `n in the expression: the first one is substituted by the PCRE engine, the second one is substitued by AutoHotkey.

[EDIT] Meanwhile, Goyyah posted another request. :-)
Well, TrimChars should work to trim spaces (give \s as string to search), it is trivial to change to do LTrim and RTrim. Goyyah, I let you try and make the change... ;-)
Posted Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")