AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Put here requests of problems with regular expressions
Goto page Previous  1, 2, 3, ... 17, 18, 19  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
majkinetor



Joined: 24 May 2006
Posts: 3644
Location: Belgrade

PostPosted: Mon Oct 23, 2006 9:05 am    Post subject: Reply with quote

2 Goyyah.

I didn't download reg exp AHK yet, so I tried examples with EditPlus. Also, note that this can be done somewhat easier as [ \t] can be replaced by \s as pointed out by PhiLho (I didn't use this as EditPlus use old reg exp syntax witch doesn't have this, but anyawy, I think you should learn it first to better understand REs)

I gave you search string in N.s and replace string in N.r.
It should look like this. So you should put it here:

Code:
 RegExReplace(String, N.s, N.r ) ; AllTrim


Also, I see that PhilHo uses $n instead \n for replacement. I am not sure if AHK supports regular \N syntax to reference group.
_________________
Back to top
View user's profile Send private message MSN Messenger
PhiLho



Joined: 27 Dec 2005
Posts: 6721
Location: France (near Paris)

PostPosted: Mon Oct 23, 2006 9:17 am    Post subject: Reply with quote

Can't resist...
Code:
MsgBox %
( Join
 ">" .
 TrimChars("||Apples|Bananas|Cherries||", "\|") . "<`n>" .
 TrimChars("Apples|Bananas|Cherries||", "\|") . "<`n>" .
 TrimChars("||Apples|Bananas|Cherries", "\|") . "<`n>" .
 TrimChars("Apples|Bananas|Cherries", "\|") . "<`n>" .
 TrimChars("     Apples|Bananas|Cherries     ", "\s", "L") . "<`n>" .
 TrimChars("     Apples|Bananas|Cherries     ", "\s", "R") . "<`n>" .
 TrimChars("     Apples|Bananas|Cherries     ", "\s") . "<"
)

TrimChars(_string, _char, _opt="")
{
   local expr

   If _opt = L
      expr = ^%_char%*
   Else If _opt = R
      expr = %_char%*$
   Else
      expr = (^%_char%*|%_char%*$)
   Return RegExReplace(_string, expr)
}

_________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")
Back to top
View user's profile Send private message Visit poster's website
PhiLho



Joined: 27 Dec 2005
Posts: 6721
Location: France (near Paris)

PostPosted: Mon Oct 23, 2006 9:46 am    Post subject: Reply with quote

OK, maximum flexibility:
Code:
MsgBox %
( Join
 "1>" .
 TrimChars("||Apples|Bananas|Cherries||", "\|") . "<`n2>" .
 TrimChars("Apples|Bananas|Cherries||", "\|") . "<`n3>" .
 TrimChars("||Apples|Bananas|Cherries", "\|") . "<`n4>" .
 TrimChars("||Apples|Bananas|Cherries||", "\|", "1") . "<`n5>" .
 TrimChars("Apples|Bananas|Cherries||", "\|", "1") . "<`n6>" .
 TrimChars("||Apples|Bananas|Cherries", "\|", "1") . "<`n7>" .
 TrimChars("||Apples|Bananas|Cherries||", "\|", "L") . "<`n8>" .
 TrimChars("||Apples|Bananas|Cherries||", "\|", "R") . "<`n9>" .
 TrimChars("     Apples|Bananas|Cherries     ", "\s", "L") . "<`nA>" .
 TrimChars("     Apples|Bananas|Cherries     ", "\s", "R") . "<`nB>" .
 TrimChars("     Apples|Bananas|Cherries     ", "\s") . "<"
)
MsgBox %
( Join
 "1>" .
 TrimChars("`n`nApples`nBananas`nCherries`n`n", "\n") . "<`n2>" .
 TrimChars("Apples`nBananas`nCherries`n`n", "\n") . "<`n3>" .
 TrimChars("`n`nApples`nBananas`nCherries", "\n") . "<`n4>" .
 TrimChars("Apples`nBananas`nCherries", "\n") . "<`n5>" .
 TrimChars("`n`nApples`nBananas`nCherries", "\n", "1") . "<`n6>" .
 TrimChars("Apples`nBananas`nCherries`n`n", "\n", "1") . "<`n7>" .
 TrimChars("`n`nApples`nBananas`nCherries`n`n", "\n", "1") . "<`n8>" .
 TrimChars("`n`nApples`nBananas`nCherries`n`n", "\n", "L") . "<`n9>" .
 TrimChars("`n`nApples`nBananas`nCherries`n`n", "\n", "R") . "<`nA>" .
 TrimChars("`n`nApples`nBananas`nCherries`n`n", "\n", "L1") . "<`nB>" .
 TrimChars("`n`nApples`nBananas`nCherries`n`n", "\n", "R1") . "<"
)

/*
// Trim out characters from the given string.
// The _char can contain any RE class, and special RE chars
// must be escaped: "!", "\|", "\s", "[,;:.]", etc.
// The option string can contain L to trim only on left,
// R to trim only on right, otherwise it will trim on both sides.
// If the option contains 1, it will trim out only one char.
*/
TrimChars(_string, _char, _opt="")
{
   local expr, quantifier, reOpt

   If _opt contains 1
      quantifier = ?
   Else
      quantifier = *

   If (_char = "`n" or _char = "\n")
   {
      lBound = \A
      rBound = \z
      reOpt = ms
   }
   Else
   {
      lBound = ^
      rBound = $
      reOpt =
   }
   If _opt contains L
      expr = %lBound%%_char%%quantifier%
   Else If _opt contains R
      expr = %_char%%quantifier%%rBound%
   Else
      expr = (%lBound%%_char%%quantifier%|%_char%%quantifier%%rBound%)
   Return RegExReplace(_string, expr, "", reOpt)
}

_________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")
Back to top
View user's profile Send private message Visit poster's website
SKAN



Joined: 26 Dec 2005
Posts: 6223

PostPosted: Mon Oct 23, 2006 10:09 am    Post subject: Reply with quote

Many thanks PhiLho, I have updated my query with the solution!
_________________
Back to top
View user's profile Send private message
SKAN



Joined: 26 Dec 2005
Posts: 6223

PostPosted: Mon Oct 23, 2006 11:06 am    Post subject: Reply with quote

How to retrieve a part of filepath in one line?

SplitPath requires two lines, whereas I would like to know if it possible with a single RegExReplace

Like:

Code:
FileName  := RegExReplace( A_Ahkpath, ... , ..)
FileExt   := RegExReplace( A_Ahkpath, ... , ..)
FileNoExt := RegExReplace( A_Ahkpath, ... , ..)


Question

Solution:

Code:
; Example written by Titan:
file := comspec
SplitPath, file, _OutFileName, _OutDir, _OutExtension, _OutNameNoExt, _OutDrive

OutFileName := RegExReplace(file, ".*\\(.*)$", "$1")
OutDir := RegExReplace(file, "(.*)\\.*$", "$1")
OutExtension := RegExReplace(file, ".*\.(.*)$", "$1")
OutNameNoExt := RegExReplace(file, ".*\\(.*)\..*", "$1")
OutDrive := RegExReplace(file, "^([A-Z]+:).*", "$1")

MsgBox, RegEx:`t %OutFileName%, %OutDir%, %OutExtension%, %OutNameNoExt%, %OutDrive%
   . `nSplitPath:`t %_OutFileName%, %_OutDir%, %_OutExtension%, %_OutNameNoExt%, %_OutDrive% .

_________________


Last edited by SKAN on Mon Oct 23, 2006 4:05 pm; edited 2 times in total
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 3644
Location: Belgrade

PostPosted: Mon Oct 23, 2006 11:59 am    Post subject: Reply with quote

\dir 1\dir 2\dir 3\dir 4\file name.ext

Code:
( ([\][^\]+){n} ) (.+)


will get you the part of the filename in last group.

Explanation:
Code:
[\]     represents "\" char
[^\]+   represents all chars up to the next \
{n}     is number of ocurances (N in this case is how many dirs you want to be skipped)
(.+)    represents everything up to the new line



So, to get \dir3\dir4\file name.ext you would set N to 2 to skip \dir1 and \dir2


I don't know specifics of AHK REs but {n} is sometimes written as {n,n} (understood as min, max)
_________________
Back to top
View user's profile Send private message MSN Messenger
Titan



Joined: 11 Aug 2004
Posts: 5376
Location: /b/

PostPosted: Mon Oct 23, 2006 12:48 pm    Post subject: Reply with quote

Goyyah wrote:
How to retrieve a part of filepath in one line?

Here is a basic example:
Code:
file := comspec
SplitPath, file, _OutFileName, _OutDir, _OutExtension, _OutNameNoExt, _OutDrive

OutFileName := RegExReplace(file, ".*\\(.*)$", "$1")
OutDir := RegExReplace(file, "(.*)\\.*$", "$1")
OutExtension := RegExReplace(file, ".*\.(.*)$", "$1")
OutNameNoExt := RegExReplace(file, ".*\\(.*)\..*", "$1")
OutDrive := RegExReplace(file, "^([A-Z]+:).*", "$1")

MsgBox, RegEx:`t %OutFileName%, %OutDir%, %OutExtension%, %OutNameNoExt%, %OutDrive%
   . `nSplitPath:`t %_OutFileName%, %_OutDir%, %_OutExtension%, %_OutNameNoExt%, %_OutDrive% .

_________________

Back to top
View user's profile Send private message Visit poster's website
PhiLho



Joined: 27 Dec 2005
Posts: 6721
Location: France (near Paris)

PostPosted: Mon Oct 23, 2006 1:17 pm    Post subject: Reply with quote

Goyyah wrote:
How to retrieve a part of filepath in one line?
I knew somebody would ask that... Smile
Frankly, I don't think it is a good idea to use REs here...
AHK's SplitPath uses a system call to do the split, and I assume it can handle all legal cases.
My code below, for example, doesn't handle UNC (\\serverName\path). I can add this, but this add even more complexity! And it is simpler to do two expressions, after checking if the string starts with a double backslash.

Just for fun, I made anyway an expression that should work on most canonical paths... And that's a good opportunity to introduce multiline expressions with comments! Smile So it is a bit more readable and self-documenting.
Code:
; Rotate or comment out these test values
somePath = \temp\install\FooSoft\config\templates\server\res\report_properties\
somePath = \temp\install\FooSoft\config\templates\server\res\report_properties
somePath = \temp\install\FooSoft\config\templates\server\res\report.properties
somePath = E:\temp\install\FooSoft\config\templates\server\res\report_properties\
somePath = E:\temp\install\FooSoft\config\templates\server\res\report_properties
somePath = E:\temp\install\FooSoft\config\templates\server\res\report.properties

re =
(
^
# The drive, capture #1
([A-Z]:)?
# The path, capture # 2
(\\      # Probably starts with a backslash
   (?:[^\\]+\\)*      # A repeated sequence of non-backslash chars followed by a slash
`)
# The file name, capture # 3
(
   # If it has an no extension
   (?:
      # A sequence of non-dot chars, capture #4
      ([^.]*)
   # Or with extension
   |
      # A sequence of any chars, capture #5
      (.*?)
      # The extension dot
      \.
      # The extension, made of at least one non-dot char, capture #6
      ([^.]+)
   `)
`)
$
)

splitResult := RegExMatch(somePath, re, "ix", splitted)
fileName := splitted3
dir := splitted2
extension := splitted6
nameNoExt := splitted4 . splitted5
drive := splitted1
MsgBox,
(
fileName: %fileName%
dir: %dir%
extension: %extension%
nameNoExt: %nameNoExt%
drive: %drive%
)
The non-extended expression is:
Code:
^([A-Z]:)?(\\(?:[^\\]+\\)*)((?:([^.]*)|(.*?)\.([^.]+)))$
I should suggest a feature that I saw nowhere up to now: since AutoHotkey handle named captures in replace strings, it could be cool to be able to specify an option telling it to transform these named captures to variables holding the capture! Thus, no need for the extra step of assigning array members to variables of more significant names.

Another way could be to add an option to return the nth capture instead of a found position. Seems more natural than using RegExReplace for this, as it constraints to match the remainder of the string to remove it.

Goyyah, I haven't exactly answered your request, but as advised, you might not want to use REs here. I give the above more for educational purpose than for practical purpose, as it is easy to find paths that make this RE choke.
You can create a function that does a SplitPath and returns the relevant part, that can be part of a standard library.
Wanting to save some lines at all costs might lead to overly complex code, hard to maintain, and that can break when not expected...
_________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")
Back to top
View user's profile Send private message Visit poster's website
SKAN



Joined: 26 Dec 2005
Posts: 6223

PostPosted: Mon Oct 23, 2006 2:54 pm    Post subject: Reply with quote

@Titan: Many thanks! Your example is very clear & works great!

PhiLho wrote:
Goyyah, I haven't exactly answered your request, but as advised, you might not want to use REs here. I give the above more for educational purpose than for practical purpose, as it is easy to find paths that make this RE choke.
You can create a function that does a SplitPath and returns the relevant part, that can be part of a standard library.
Wanting to save some lines at all costs might lead to overly complex code, hard to maintain, and that can break when not expected...


I understand PhiLho.. Thanks for the caution!
Many thanks as well as for the elaborate postings you have been making in this topic. Very useful!

I am likely to use those RegExReplace solutions where I am very sure.
For example, for making a list of image files in a folder:

Code:
SetWorkingDir, %A_Windir%
Haystack := "BMP|JPG|PNG|GIF"
Loop, *.*
 If InStr(HayStack, RegExReplace(A_Loopfilename, ".*\.(.*)$", "$1") )
  ImageFiles := RegExReplace(ImageFiles . "`n" A_LoopfileName, "^\n?(.*?)\n?$", "$1")
MsgBox, % ImageFiles


There is redundant checking of starting linefeed which I should replace with a StringTrimLeft outside the loop. The script would be slow as it is. I am aware of it so please do not ridicule it.

Smile
_________________
Back to top
View user's profile Send private message
PhiLho



Joined: 27 Dec 2005
Posts: 6721
Location: France (near Paris)

PostPosted: Mon Oct 23, 2006 3:15 pm    Post subject: Reply with quote

I certainly won't ridicule it, but I think that you overdo a bit here, don't use REs everywhere, even if I put them in lot of answers...
Code:
extensions = BMP|JPG|PNG|GIF
re := "i)(" . extension . ")$"
Loop E:\Dev\PhiLhoSoft\AutoHotkey\Images\*.*
   If RegExMatch(A_Loopfilename, re)
      imageFiles := imageFiles . A_LoopFileName . "`n"
StringTrimRight imageFiles, imageFiles, 1
MsgBox %imageFiles%
Don't say it is x% longer! Smile
Re-reading your post, I understand it now, as I did what you wrote you avoided... Frankly, which version do you prefer?
I prefer mine, as I didn't even tried to understand your RE...

[EDIT] I moved the option from a separate parameter to the RE "i)", to work with the latest beta.
_________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")


Last edited by PhiLho on Tue Oct 24, 2006 10:54 am; edited 3 times in total
Back to top
View user's profile Send private message Visit poster's website
SKAN



Joined: 26 Dec 2005
Posts: 6223

PostPosted: Mon Oct 23, 2006 3:51 pm    Post subject: Reply with quote

Thats very nice! Very Happy, though it lists ListOfBMPfiles.txt which I am able to overcome by adding a period before the extensions in the extensions string! Still it will list Files.BMP.txt so I think Titan's RegEx would suit the need. OfCourse, I know that my code looks least readable! Sad

Thanks for the idea-provoking example! All the time I was only thinking about RegExReplace and totally forgot RegExMatch!

RegEx is as tough as DllCall().. But I will catch up soon! Very Happy

...
_________________
Back to top
View user's profile Send private message
PhiLho



Joined: 27 Dec 2005
Posts: 6721
Location: France (near Paris)

PostPosted: Mon Oct 23, 2006 4:23 pm    Post subject: Reply with quote

Goyyah wrote:
Thats very nice! Very Happy, though it lists ListOfBMPfiles.txt which I am able to overcome by adding a period before the extensions in the extensions string! Still it will list Files.BMP.txt
Yes, stupid me, I added the $ at last second, but it won't work, so instead of:
re := extension . "$"
use:
re := "\.(" . extension . ")$"
Of course, you can write this directly: re = \.(BMP|JPG|PNG|GIF)$, I just wanted to isolate the list of extensions from the RE mechanism.
Maybe someday we will have a Loop RegExFilePattern...
_________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")
Back to top
View user's profile Send private message Visit poster's website
SKAN



Joined: 26 Dec 2005
Posts: 6223

PostPosted: Mon Oct 23, 2006 4:52 pm    Post subject: Reply with quote

Many thanks! Works fine:

Listing files that match specified file extensions:

Code:
Loop %A_WinDir%\*.*
   If RegExMatch(A_Loopfilename, "\.(BMP|JPG)$", "i")
      imageFiles := imageFiles . A_LoopFileName . "`n"
StringTrimRight imageFiles, imageFiles, 1
MsgBox %imageFiles%


Smile
_________________
Back to top
View user's profile Send private message
majkinetor !
Guest





PostPosted: Mon Oct 23, 2006 5:06 pm    Post subject: Reply with quote

That would be very slow for large directories....
Back to top
SKAN



Joined: 26 Dec 2005
Posts: 6223

PostPosted: Mon Oct 23, 2006 5:35 pm    Post subject: Reply with quote

majkinetor ! wrote:
That would be very slow for large directories....


I tested it:

Code:
A_Tc := A_TickCount

Loop C:\*.*,0,1
   If RegExMatch(A_Loopfilename, "\.(BMP|JPG|GIF)$", "i")
      imageFiles := imageFiles . A_LoopFileLongPath . "`n"
StringTrimRight imageFiles, imageFiles, 1

MsgBox % A_TickCount - A_Tc ; 84 Seconds
MsgBox %imageFiles%

imageFiles=
A_Tc := A_TickCount

Loop C:\*.*,0,1
{
   SplitPath, A_LoopFileName,,,Ext
   If Ext in BMP,JPG,GIF
      imageFiles := imageFiles . A_LoopFileLongPath . "`n"
}
StringTrimRight imageFiles, imageFiles, 1

MsgBox % A_TickCount - A_Tc ; 133 Seconds
MsgBox %imageFiles%


Conclusion: RegEx is faster than the conventional method!

Cool
_________________
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help All times are GMT
Goto page Previous  1, 2, 3, ... 17, 18, 19  Next
Page 2 of 19

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group