Help with a reference to regex group

Please check the FAQ (https://www.xyplorer.com/faq.php) before posting a question...
John_C
Posts: 336
Joined: 16 May 2018 20:04

Help with a reference to regex group

Post by John_C »

I'm trying to write a simple script to copy the files in the following way:

Code: Select all

from  filename_with_multiple_exts.user.js
to    filename_with_multiple_exts.user.js@1300.user.js   // 13:00 is the current time (1:00 pm)
Here is what I tried:

Code: Select all

doesn't work
::$a = regexmatches("<curname>", "^([^.]*)\.(.*)$"); copyas '<curname>@<date HHmm>.' . $2;

as well as this
::$a = regexmatches("<curname>", "^([^.]*)\.(.*)$"); copyas '<curname>@<date HHmm>.' . $a$2;
The problem is that $2 doesn't work.

highend
Posts: 14954
Joined: 06 Feb 2011 00:33
Location: Win Server 2022 @100%

Re: Help with a reference to regex group

Post by highend »

Em, what?

Referencing a group can only be done inside the command^^
regexmatches() doesn't know anything about capturing groups^^

So this would be either done via regexreplace() or without
groups at all, e.g.:

Code: Select all

::$a = regexmatches(<curname>, "(\.([^.]+)){2}$"); copyas '<curname>@<date HHmm>' . $a;
One of my scripts helped you out? Please donate via Paypal

John_C
Posts: 336
Joined: 16 May 2018 20:04

Re: Help with a reference to regex group

Post by John_C »

Thanks. It seems it could be even simpler:

Code: Select all

::$a = regexmatches(<curname>, "\..*$"); copyas '<curname>@<date HHmm>' . $a;
Though I'm not really happy that regex includes the initial period...

highend
Posts: 14954
Joined: 06 Feb 2011 00:33
Location: Win Server 2022 @100%

Re: Help with a reference to regex group

Post by highend »

Thanks. It seems it could be even simpler
As long as everything after the first dot should be captured? Sure.
One of my scripts helped you out? Please donate via Paypal

John_C
Posts: 336
Joined: 16 May 2018 20:04

Re: Help with a reference to regex group

Post by John_C »

Yes, everything after the first dot.

I have tried these two versions to exclude the dot itself:

* https://regex101.com/r/NAc2rg/2
* https://regex101.com/r/NAc2rg/3

Code: Select all

::$a = regexmatches(<curname>, '(?<=\.).*'); copyas '<curname>@<date HHmm>' . $a;
::$a = regexmatches(<curname>, '\.\K.*'); copyas '<curname>@<date HHmm>' . $a;
Seems it doesn't work in XYplorer...

highend
Posts: 14954
Joined: 06 Feb 2011 00:33
Location: Win Server 2022 @100%

Re: Help with a reference to regex group

Post by highend »

Neither lookbehinds nor keep outs are supported by VB6 regex...
You could just trim the result...
One of my scripts helped you out? Please donate via Paypal

John_C
Posts: 336
Joined: 16 May 2018 20:04

Re: Help with a reference to regex group

Post by John_C »

Well, this is the version that looks good to my opinion. I will use it:

Code: Select all

::$exts = regexreplace(<curname>, '^[^\.]+\.?'); copyas '<curname>@<date HHmm>' . '.' . $exts;

highend
Posts: 14954
Joined: 06 Feb 2011 00:33
Location: Win Server 2022 @100%

Re: Help with a reference to regex group

Post by highend »

1. There is no need to escape a dot in a range
2. This is even shorter: ^.+?\. (for the given example)
One of my scripts helped you out? Please donate via Paypal

John_C
Posts: 336
Joined: 16 May 2018 20:04

Re: Help with a reference to regex group

Post by John_C »

highend wrote: 05 Dec 2019 21:34 1. There is no need to escape a dot in a range
2. This is even shorter: ^.+?\. (for the given example)
highend, could you help a little more?

Here is my script to copy the files and directories:

Code: Select all

::$exts = regexreplace(<curname>, '^[^\.]+\.?');
if ($exts == '') {
    copyas '<curname>@<date hhnn>';
}
else {
    $exts = regexreplace($exts, '^.+@\d+\.');
    copyas '<curname>@<date hhnn>' . '.' . $exts;
}
I use it as a one-liner.

Consider a file with double extension user.js. It will be copied as follows:

Code: Select all

a.user.js => a.user.js@1300.user.js
However, it doesn't work correctly when I have multiple files selected. For example:

Code: Select all

Select
a.aaa.js
b.bbb.js

Run the script. The files will be copied as
a.aaa.js@1300.aaa#2.js
b.bbb.js@1300.aaa#2.js

or
a.aaa.js@1300.bbb#2.js
b.bbb.js@1300.bbb#2.js
1300 is the current time. #2 is my incremental affix (yes, it starts from 2).

I understand what is going on, but I don't know how to fix it.

highend
Posts: 14954
Joined: 06 Feb 2011 00:33
Location: Win Server 2022 @100%

Re: Help with a reference to regex group

Post by highend »

<curname> references the wrong item when more than one are selected...

Code: Select all

    $date = <date hhnn>;
    foreach($item, <get SelectedItemsNames |>, , "e") {
        $exts = regexreplace($item, '^[^\.]+\.?');
        if ($exts == '') {
            copyas $item . "@$date", , $item;
        } else {
            $exts = regexreplace($exts, '^.+@\d+\.');
            copyas $item . "@$date" . '.' . $exts, , $item;
        }
    }
One of my scripts helped you out? Please donate via Paypal

John_C
Posts: 336
Joined: 16 May 2018 20:04

Re: Help with a reference to regex group

Post by John_C »

Thanks. It seems it should be

Code: Select all

$date = <date hhnn>;
foreach($item, <get SelectedItemsNames |>, , 'e') {
    $exts = regexreplace($item, '^[^\.]+\.?');
    if ($exts == '') {
        copyas $item . '@' . $date, , $item;
    } else {
        $exts = regexreplace($exts, '^.+@\d+\.');
        copyas $item . '@' . $date . '.' . $exts, , $item;
    }
}
I changed the location of the quotes.

Without this change, I wasn't able to run it with cmd.exe.

John_C
Posts: 336
Joined: 16 May 2018 20:04

Re: Help with a reference to regex group

Post by John_C »

Is it possible to make it work with files currently stored in the clipboard, instead of the selected ones?

I tried to change the second line in different ways, e.g.

Code: Select all

foreach($item, <get clipboard |>, , 'e')
foreach($item, <get clipboard>, , 'e')
foreach($item, <get clipboard>, <crlf>, 'e')
foreach($item, <clipboard>, <crlf>, 'e')
but these changes doesn't work.

highend
Posts: 14954
Joined: 06 Feb 2011 00:33
Location: Win Server 2022 @100%

Re: Help with a reference to regex group

Post by highend »

foreach($item, <clipboard>, <crlf>, 'e')
should work (depending on if the files are really separated by <crlf>). But without knowing what's inside your clipboard...
One of my scripts helped you out? Please donate via Paypal

John_C
Posts: 336
Joined: 16 May 2018 20:04

Re: Help with a reference to regex group

Post by John_C »

Thanks a lot. Sorry that sometimes I don't read the docs with enough patience.

What I really trying to accomplish is to recreate the same behavior as described few posts above with 2 differences:

* It should work for copy, not for duplicate
* It should work with incremental affix, not the date one.

That is, you select one or multiple files, then press Ctrl-C and Ctrl-V, and the file will be copied as follows:

Code: Select all

file.user.js => file#2.user.js
file.user.js => file#3.user.js
file.user.js => file#4.user.js
etc
Below is what I have currently.

It works, but not correctly, I will be greatly appreciated for help.

The problem is that I need the incremental affix, not the date one. But it seems that XY doesn't have the variable for it.

Code: Select all

::$affix = <date hhnn>;
foreach($item, <clipboard>, <crlf>, 'e') {
    $filename = regexmatches($item, '[^\\]+$');
    $exts = regexreplace($item, '^[^\.]+\.?');
    copyas $filename . '#' . $affix . '.' . $exts,, $item;
}
In real life, the script is intended to work trough AutoHotkey, and therefore, for convenience, I post AutoHotkey version as well:

Code: Select all

#SingleInstance Force
SetTitleMatchMode 2
XYplorerDir := "C:\PrgFiles\XYplorer"

#If WinActive("ahk_exe XYplorer.exe")

^v::
    Run % XYplorerDir . "\XYplorer.exe /script=" . """"
        . "::$affix = <date hhnn>;"
        . "foreach($item, <clipboard>, <crlf>, 'e') {"
            . "$filename = regexmatches($item, '[^\\]+$');"
            . "$exts = regexreplace($item, '^[^\.]+\.?');"
            . "copyas $filename . '#' . $affix . '.' . $exts,, $item;"
        . "}" . """" . A_Space . "/flg=2"
Return

highend
Posts: 14954
Joined: 06 Feb 2011 00:33
Location: Win Server 2022 @100%

Re: Help with a reference to regex group

Post by highend »

And where exactly is the problem now?

01. Get the affix from XY's .ini file by reading "PostfixNum" from the "General" section via getkey()
02. In the foreach() loop
- Get the digits in the affix via a regexmatch()
- Count the number(s) of the captured digits (so that it would work for e.g. #02 as well!) via strlen()
- Generate the first $dstFile name (this time by just inserting the normal affix)
- Now use a while(true) loop
-- Check if the $dstFile already exists via exists()
-- If not, do the copying and break the while loop
-- If yes
---- Increase the digits from the affix by one
---- Format this value with the count value from above and replace the digits in the affix with this new value via format() and strrepeat()
---- Generate the new $dstFile name with this new (counted up) affix
---- The loop will continue until it DOES NOT find a file name that already exists

With this strategy and e.g. an affix of " [02]"
and existing names like:

Code: Select all

file.user.js
file [02].user.js
file [05].user.js
the next run of the script (and "file.user.js" still in the clipboard) it would generate the next missing file [03].user.js file...
One of my scripts helped you out? Please donate via Paypal

Post Reply