#11 2008-08-17 00:40

krtek
Senior Member
From: Łódź (Poland)
Registered: 2008-02-21
Posts: 262

Re: Removing a simbol at last position

Unfortunately, RegEx engine that is used in ReNamer doesn't support that kind of tags in replace part of regex (although they exist, and it is possible to do such a job with regexes if they are fully implemented; but unfortunately - not in ReNamer)...
But you can do that with PascalScript using eg. regex functions of PascalScript, especially:
function SubMatchesRegEx(const Input, Find: WideString; const CaseSensitive: Boolean): TStringsArray;
which for given filename (Input) will create an array of  matching groups for a given regex (Find).
So if you get your example as an Input:
David Guetta Feat. Chris Willis - Love Is Gone (Original Mix).mp3
and regex: "\w+\s(\w+) Feat. \w+\s(\w+) - .+"
it should create an array of two strings: Guetta and Willis (groups are strings that are matched by regex inside brackets).

Then you can use
function WideUpperCase(const S: WideString): WideString;
on these strings and glue it back together for nice filename.

Let me know if you succeded. Otherwise I write it for you.

For more info about regex functions in PascalScript take a look at
http://www.den4b.com/forum/viewtopic.php?id=433

Cheers,
Konrad

Last edited by krtek (2008-08-17 00:46)


Regular Expressions are not as hard to understand as you may think. Check ReNamer's manual or nice Regular Expressions tutorial for more info and start to use full power of applications that use them (like ReNamer, Mp3Tag and so on).

Offline

#12 2008-08-17 02:27

eR@SeR
Senior Member
From: Земун, Србија
Registered: 2008-01-23
Posts: 353

Re: Removing a simbol at last position

Unfortunately, RegEx engine that is used in ReNamer doesn't support that kind of tags in replace part of regex (although they exist, and it is possible to do such a job with regexes if they are fully implemented; but unfortunately - not in ReNamer)...

If they exist like you said, I hope that Denis will implement these tags, if is possible of course roll


I read the posts at ReplaceRegEx and MatchesRegEx functions in PascalScript, but I cannot figure out where to put function SubMatchesRegEx(const Input, Find: WideString; const CaseSensitive: Boolean): TStringsArray; sad
As I said before I'm not experienced with Pascal, so could you make a script? big_smile

Make those parts in code bold to emphasize future possible edits, too; I hope that script which you'll write is universal for any case changings, in every possible word in filename, only you should specify the lenght (pattern) of filename using RegEx, in this case "\w+\s(\w+) Feat. \w+\s(\w+) - .+", and then do WideUpperCase or other function for case change you need for, right? hmm

Last edited by eR@SeR (2008-08-17 02:30)


TRUTH, FREEDOM, JUSTICE and FATHERLAND are the highest morale values which human is born, lives and dies for!

Offline

#13 2008-08-17 11:01

krtek
Senior Member
From: Łódź (Poland)
Registered: 2008-02-21
Posts: 262

Re: Removing a simbol at last position

If they exist like you said, I hope that Denis will implement these tags, if is possible of course

It's out of Dennis power, because he uses third party regex engine.
More info in: http://www.den4b.com/forum/viewtopic.php?id=428

I'll write the script when I find some spare time. I'm moving from UK back to Poland tomorrow, so it might take some time.

Last edited by krtek (2008-08-17 11:03)


Regular Expressions are not as hard to understand as you may think. Check ReNamer's manual or nice Regular Expressions tutorial for more info and start to use full power of applications that use them (like ReNamer, Mp3Tag and so on).

Offline

#14 2008-08-18 17:49

eR@SeR
Senior Member
From: Земун, Србија
Registered: 2008-01-23
Posts: 353

Re: Removing a simbol at last position

I'll write the script when I find some spare time...

No need for rush... Relax and rest in Poland and have a nice trip (maybe this wish is overdue) sad

Thanks anyway for making things clear... wink

Cheers


TRUTH, FREEDOM, JUSTICE and FATHERLAND are the highest morale values which human is born, lives and dies for!

Offline

#15 2009-02-15 23:15

krtek
Senior Member
From: Łódź (Poland)
Registered: 2008-02-21
Posts: 262

Re: Removing a simbol at last position

The DAY has come big_smile
Sorry for lating so #%@!#  long, eR@SeR.
But it works!

const
REGEX = '.+\s(\w+) Feat. \w+\s(\w+) - .+|.+\s(\w+)\s-\s.+';

REGEX2 = '.+\s(\w+)\s-\s.+';                     //you won't need these two (it's just the one above splitted in halves)
REGEX3 = '.+\s(\w+) Feat. \w+\s(\w+) - .+';

CASE_SENSITIVE = False;

var
  Matches, SubPatterns : TStringsArray;
  TempFilename : WideString;
  start_pos, end_pos, i : Integer;
  Initialized : Boolean;
  
  

begin
  TempFilename:='';
  end_pos:=0;
  start_pos:=1;
  SetLength(SubPatterns,0);
  SetLength(Matches,0);
  
  
  Matches:=MatchesRegEx(Filename, REGEX, CASE_SENSITIVE);
  if Length(Matches) <= 0 then exit;
  if Matches[0] <> Filename then 
     if DialogYesNo('RegEx didn''t match the full filename.' +#10+ 'Would you like to continue?')=false then exit;
  SubPatterns:=SubMatchesRegEx(Matches[0],REGEX,CASE_SENSITIVE);
  if Length(SubPatterns) <=0 then exit;
  
  for i:=0 to Length(SubPatterns)-1 do
    if SubPatterns[i]<>'' then
    begin
      end_pos:=WidePos(SubPatterns[i], Matches[0])-1;
      TempFileName:=TempFileName+WideCopy(Matches[0], start_pos, end_pos-start_pos+1);
      start_pos:=end_pos+Length(SubPatterns[i])+1;
      TempFilename:=TempFileName+WideUpperCase(SubPatterns[i]);
    end;
  if start_pos < Length(Matches[0]) then
    TempFilename:=TempFileName+WideCopy(Matches[0], start_pos, Length(Matches[0])-start_pos+1);
 
 FileName:=TempFileName;
 
end.

Last edited by krtek (2009-02-15 23:16)


Regular Expressions are not as hard to understand as you may think. Check ReNamer's manual or nice Regular Expressions tutorial for more info and start to use full power of applications that use them (like ReNamer, Mp3Tag and so on).

Offline

#16 2009-02-16 03:11

eR@SeR
Senior Member
From: Земун, Србија
Registered: 2008-01-23
Posts: 353

Re: Removing a simbol at last position

Doesn't matter, important thing is that you gave respond and thanks for that wink

It works for following examples as I asked:

David GUETTA Feat. Chris WILLIS - Love Is Gone (Original Mix).mp3

and

Eddy WATA - I Love My People.mp3
Geo Da SILVA - Feelin' So Good (Long Mix).mp3

I noticed this...if you want to use And, &, Featuring, Ft. instead Feat. you can edit code in first REGEX (second line of code), type one of it and you'll get the same output. Excellent cool

Sorry for "making your life harder"...could you help with these ones? roll

Jean-Michel Jarre --> Jean-Michel JARRE
Predrag Stojakovic --> Predrag STOJAKOVIC
Geo Da Silva --> Geo Da SILVA

Tip: code will make last word UPPER no matter what's in front of it (if possible).
Note: It will be used for names and surnames.

Important (!) question:
Your code makes ALL UPPER CASE in these examples...so is there a line in code that we can change/edit to do all lower case or First letter capital manipulation or you should create new one for that?
Refering to your new code too (second example)!

P.S. IMO your feedback here can give enough answers/solutions for these situations so go ahead BUT you don't have to hurry wink


TRUTH, FREEDOM, JUSTICE and FATHERLAND are the highest morale values which human is born, lives and dies for!

Offline

#17 2009-02-16 10:47

krtek
Senior Member
From: Łódź (Poland)
Registered: 2008-02-21
Posts: 262

Re: Removing a simbol at last position

Just a quick reply:

There is a line in the code:

TempFilename:=TempFileName+WideUpperCase(SubPatterns[i]);

If you change that function for  WideLowerCase you'll get all lowercase. First letter capital would need something like that:

TempFilename:=TempFileName+WideUpperCase(SubPatterns[i][1])+WideLowerCase(WideCopy(SubPatterns[i], 2, Length(SubPatterns[i])-1));

I will play a bit more with that script, to make these things easier...

eR@SeR wrote:

Tip: code will make last word UPPER no matter what's in front of it (if possible).
Note: It will be used for names and surnames.

And what about things that are AFTER that surname, eg. song title?
If there is nothing after then this regex should be enough:
'.+\s(\w+)$'

Hmmm... But we need to match for the filename without extention... Ok, quick patch.

const
REGEX = '.+\s(\w+)$';

REGEX2 = '.+\s(\w+) Feat. \w+\s(\w+) - .+|.+\s(\w+)\s-\s.+';       //just a backup of the old regex

CASE_SENSITIVE = False;

var
  Matches, SubPatterns : TStringsArray;
  TempFilename, FileNameNoEXT : WideString;
  start_pos, end_pos, i : Integer;
  Initialized : Boolean;
  
  

begin
  TempFilename:='';
  end_pos:=0;
  start_pos:=1;
  SetLength(SubPatterns,0);
  SetLength(Matches,0);
  FileNameNoEXT:=WideStripExtension(FileName);
  
  
  Matches:=MatchesRegEx(FileNameNoEXT, REGEX, CASE_SENSITIVE);
  if Length(Matches) <= 0 then exit;
  if Matches[0] <> FileNameNoEXT then 
     if DialogYesNo('RegEx didn''t match the full filename.' +#10+ 'Would you like to continue?')=false then exit;
  SubPatterns:=SubMatchesRegEx(Matches[0],REGEX,CASE_SENSITIVE);
  if Length(SubPatterns) <=0 then exit;
  
  for i:=0 to Length(SubPatterns)-1 do
    if SubPatterns[i]<>'' then
    begin
      end_pos:=WidePos(SubPatterns[i], Matches[0])-1;
      TempFileName:=TempFileName+WideCopy(Matches[0], start_pos, end_pos-start_pos+1);
      start_pos:=end_pos+Length(SubPatterns[i])+1;
      TempFilename:=TempFileName+WideUpperCase(SubPatterns[i]);
    end;
  if start_pos < Length(Matches[0]) then
    TempFilename:=TempFileName+WideCopy(Matches[0], start_pos, Length(Matches[0])-start_pos+1);
 
 FileName:=TempFileName+WideExtractFileExt(FileName);
 
end.

It works for both examples. You just need to change regex at the beginning.
Tell me how it works.

Edited 16.02.2009 19:00
Few words of comment, how it works. The script changes case of every backrefference match (so it will alter case of every part of the whole match that is in parenthesis () in regex).

If you know that, you can use regex like that:
'.+\s(\w+)\s(Feat\.|ft\.|&|And|Featuring)\s\w+\s(\w+) - .+|.+\s(\w+)\s-\s.+'
and make all the Feat., ft., & and anything else in one go (just remember to escape dots "\.").
The only drawback is that all these words will have the case changed by the script (because they must to be appear in parenthesis; otherwise the alternation would be widened for whole expression).
But I guess it might be easier to do it in one go, and then simply replace these few words with same words in correct case, eg. FEAT->Feat, FT->ft and so on...

Last edited by krtek (2009-02-22 17:04)


Regular Expressions are not as hard to understand as you may think. Check ReNamer's manual or nice Regular Expressions tutorial for more info and start to use full power of applications that use them (like ReNamer, Mp3Tag and so on).

Offline

#18 2009-02-16 22:47

krtek
Senior Member
From: Łódź (Poland)
Registered: 2008-02-21
Posts: 262

Re: Removing a simbol at last position

I've got something special.
Renewed script with:

1. Basic error handling (it will ask what to do if regex won't match full FileName)
2. Skipping of given words (so you can do your job in one go: just write good regex and tell the script which words to omit)
3. All controls at the beginning (set CHANGE_CASE to 1 for Uppercase, 2 for Lowercase, 3 for First letter capital)

I hope it was worth so long waiting.
With that regex it will react for words Feat., ft., &, And,  Featuring... But you can add more.

const

//SCRIPT CONTROLS:

//Legend:
//1. Uppercase
//2. Lowercase
//3. First letter capital
CHANGE_CASE = 1;

REGEX = '.+\s(\w+)\s(Feat\.|ft\.|&|And|Featuring)\s\w+\s(\w+) - .+|.+\s(\w+)\s-\s.+';

//Backup REGEX's
//'.+\s(\w+) Feat. \w+\s(\w+) - .+|.+\s(\w+)\s-\s.+';
//'.+\s(\w+)$'; 


TO_SKIP = 'Feat.|ft.|&|And|Featuring';      //Here you can put words that you want to be skipped by script.
                                            //The case convertion won't be applied to them.
                                            //Seperate them with DELIMITER
                                            //And remember that you need to make them explicit. Remove any escape signs.
                                            //They need to be strings already matched by regex, so Feat. instead of Feat\.

DELIMITER = '|';                      //Delimiter of words in TO_SKIP string




CASE_SENSITIVE = False;      //Should searching with regex be case sensitive? Default: False

//END OF SCRIPT CONTROLS




var
  Matches, SubPatterns : TStringsArray;
  TempFilename, FileNameNoEXT : WideString;
  start_pos, end_pos, i, j : Integer;
  Initialized, TimeToExit, NeedSkipping, NotAFullMatch : Boolean;
  Skip : TStringsArray;
  Answer : WideString;
  


procedure Initialize;
begin
  Skip:=WideSplitString(TO_SKIP, DELIMITER);
  Answer:='Type just word BREAK in here to exit the script';
end;



begin
  
if not TimeToExit then
begin

  if not Initialized then Initialize;

  TempFilename:='';
  end_pos:=0;
  start_pos:=1;
  SetLength(SubPatterns,0);
  SetLength(Matches,0);
  NotAFullMatch:=false;
  FileNameNoEXT:=WideStripExtension(FileName);
  
  
  Matches:=MatchesRegEx(FileNameNoEXT, REGEX, CASE_SENSITIVE);
  if Length(Matches) <= 0 then exit;
  if Matches[0] <> FileNameNoEXT then NotAFullMatch:=true;
  SubPatterns:=SubMatchesRegEx(Matches[0],REGEX,CASE_SENSITIVE);
  if Length(SubPatterns) <=0 then exit;
  
  for i:=0 to Length(SubPatterns)-1 do
    if SubPatterns[i]<>'' then
    begin
      NeedSkipping:=false;
      end_pos:=WidePos(SubPatterns[i], Matches[0])-1;
      TempFileName:=TempFileName+WideCopy(Matches[0], start_pos, end_pos-start_pos+1);
      start_pos:=end_pos+Length(SubPatterns[i])+1;
      
      for j:=0 to Length(Skip)-1 do
        if WideSameText(SubPatterns[i],Skip[j]) then NeedSkipping:=true;

      if not NeedSkipping then 
        case CHANGE_CASE of
          1 : TempFilename:=TempFileName+WideUpperCase(SubPatterns[i]);
          2 : TempFilename:=TempFileName+WideLowerCase(SubPatterns[i]);
          3 : TempFilename:=TempFileName+WideUpperCase(SubPatterns[i][1])+WideLowerCase(WideCopy(SubPatterns[i], 2, Length(SubPatterns[i])-1));
        else
          begin  
            ShowMessage('The value of CHANGE_CASE constant is invalid. Check legend for info.');
            TimeToExit:=True;
            break;
          end;
        end
      else
        TempFilename:=TempFileName+SubPatterns[i];


    end;
  if start_pos < Length(FileNameNoEXT) then
    TempFilename:=TempFileName+WideCopy(FileNameNoEXT, start_pos, Length(FileNameNoEXT)-start_pos+1);
 
 if NotAFullMatch then
   if not WideInputQuery('RegEx didn''t match the full filename.', 'Old filename:'+#10+FileName+#10+#10+'Proposed new filename: '+#10+TempFileName+WideExtractFileExt(FileName)+#10+#10+'What should we do?'#10+#10+'Pressing OK button = Rename that file'+#10+'Pressing Cancek button = Skip that file'+#10+'Type ''break'' in the text field to exit the script'+#10, Answer) then
     exit
   else if WideSameText(WideLowerCase(Answer),'break') then 
       begin
         TimeToExit:=True;
         exit;
       end
   else
       Answer:='Type just word BREAK in here to exit the script';
 
     
 FileName:=TempFileName+WideExtractFileExt(FileName);

end
else exit;
 
end.

Cheers,
Konrad

Last edited by krtek (2009-02-17 06:56)


Regular Expressions are not as hard to understand as you may think. Check ReNamer's manual or nice Regular Expressions tutorial for more info and start to use full power of applications that use them (like ReNamer, Mp3Tag and so on).

Offline

#19 2009-02-22 03:24

eR@SeR
Senior Member
From: Земун, Србија
Registered: 2008-01-23
Posts: 353

Re: Removing a simbol at last position

Sorry for long reply I was busy lately...

WOW, your last code is brilliant cool
It does almost 'anything'. Like you said:

(so you can do your job in one go: just write good regex and tell the script which words to omit)

I hope it was worth so long waiting.

YES! big_smile

Nothing more to add...

Cheers wink


TRUTH, FREEDOM, JUSTICE and FATHERLAND are the highest morale values which human is born, lives and dies for!

Offline

#20 2009-07-26 16:25

krtek
Senior Member
From: Łódź (Poland)
Registered: 2008-02-21
Posts: 262

Re: Removing a simbol at last position

Hi again,
I needed to upgrade the script a bit, so I post it here for you guys as well.

Now you can choose the different case for EVERY capturing group.
And you can skip extention if you want.
ATTENTION: I've changed the meaning of digits for case functions to match the order in ReNamer's Case Rule.
I've also added iNVERT cASE and No changes possibility. The last one made TO_SKIP string obsolete so script works quicker now.

I guess it would be nice to add FORCE CASE FOR FRAGMENTS as well.
But I don't think I would be able to do this in an elegant way.
Dennis, maybe you could share your function for that part of Case Rule? Of course if it is "scriptable" (possible to transfer into the scipt big_smile ).

For now you can use Force Case For Fragments from Case Rule (with "none of the above") just after that script.

const

//SCRIPT CONTROLS:

REGEX = '(.+) - (.+) - (.+)';
CHANGE_CASE = '103';  

SKIP_EXTENTION = true;          //true or false
CASE_SENSITIVE = False;        //Should searching with regex be case sensitive? Default: False
FULL_MATCH_CHECK = True;   //Should the script warn you if regex didn't match the full filename? Default: True;
         

//Legend for CHANGE_CASE parameter:
//1. Capitalize Every Word
//2. lowercase
//3. UPPERCASE
//4. iNVERT cASE
//5. First letter capital
//0. No changes
//You may specify case for every capturing group (brackets) in regex as a string of appropriate digits.
//If the CHANGE_CASE string is shorten then number of capturing groups then the last digit is used till the end of regex.
//If the CHANGE_CASE string is longer, spare digits are ignored. 
//eg. '102' means that first matched brackets will be uppercased, second - won't be changed and third (and every brackets after it) - lowercased.



//END OF SCRIPT CONTROLS


BREAK_STRING = 'BREAK';
FOR_ALL_STRING = 'DO NOT ASK';
STANDARD_ANSWER = BREAK_STRING+' to exit, '+FOR_ALL_STRING+' to continue';



var
  Matches, SubPatterns : TStringsArray;
  TempFilename, FileNameProcessedPart : WideString;
  start_pos, end_pos, i, j : Integer;
  Initialized, TimeToExit, NotAFullMatch, CheckIfFullMatch : Boolean;
  CaseFlags : array of Integer;
  CaseFlag : Integer;
  Answer : WideString;
  


function SetCaseFlags(s : WideString) : array of Integer;
var
i : Integer;
LoopEnd : Integer;
CaseIDs : array of Integer;

begin

  SetLength(CaseIDs,Length(s));
 
  LoopEnd:=Length(s)-1;
  for i:=0 to LoopEnd do
    begin
      CaseIDs[i]:= StrToInt(WideCopy(s,1,1));
      s:=WideCopy(s,2,Length(s)-1);
    end;

  result:= CaseIDs;
end;


procedure Initialize;

begin
  Answer:=STANDARD_ANSWER;
  CheckIfFullMatch:=FULL_MATCH_CHECK;
  Initialized:=true;
  CaseFlags:=SetCaseFlags(CHANGE_CASE);
end;



begin
  
if not TimeToExit then
begin

  if not Initialized then Initialize;

  TempFilename:='';
  end_pos:=0;
  start_pos:=1;
  SetLength(SubPatterns,0);
  SetLength(Matches,0);
  NotAFullMatch:=false;
  
  if SKIP_EXTENTION then
    FileNameProcessedPart:=WideStripExtension(FileName)
  else 
    FileNameProcessedPart:=FileName;
  
  
  Matches:=MatchesRegEx(FileNameProcessedPart, REGEX, CASE_SENSITIVE);
  if Length(Matches) <= 0 then exit;
  if Matches[0] <> FileNameProcessedPart then NotAFullMatch:=true;
  SubPatterns:=SubMatchesRegEx(Matches[0],REGEX,CASE_SENSITIVE);
  if Length(SubPatterns) <=0 then exit;
  
  for i:=0 to Length(SubPatterns)-1 do
    if SubPatterns[i]<>'' then
    begin
      end_pos:=WidePos(SubPatterns[i], Matches[0])-1;
      TempFileName:=TempFileName+WideCopy(Matches[0], start_pos, end_pos-start_pos+1);
      start_pos:=end_pos+Length(SubPatterns[i])+1;
      

      if i < length(CaseFlags)  then
        CaseFlag:=CaseFlags[i]
      else 
        CaseFlag:=CaseFlags[Length(CaseFlags)-1];
        
      case CaseFlag of
        0 : TempFilename:=TempFileName+SubPatterns[i];
        1 : TempFilename:=TempFileName+WideCaseCapitalize(SubPatterns[i]);   
        2 : TempFilename:=TempFileName+WideLowerCase(SubPatterns[i]);
        3 : TempFilename:=TempFileName+WideUpperCase(SubPatterns[i]);
        4 : TempFilename:=TempFileName+WideCaseInvert(SubPatterns[i]);
        5 : TempFilename:=TempFileName+WideUpperCase(SubPatterns[i][1])+WideLowerCase(WideCopy(SubPatterns[i], 2, Length(SubPatterns[i])-1));
          
        else
          begin  
            ShowMessage('The value of CHANGE_CASE constant is invalid. Check legend for info.');
            TimeToExit:=True;
            break;
          end;
     end;

   end;
  
  
  if start_pos < Length(FileNameProcessedPart) then
    TempFilename:=TempFileName+WideCopy(FileNameProcessedPart, start_pos, Length(FileNameProcessedPart)-start_pos+1);
 

  if NotAFullMatch then
    if CheckIfFullMatch then    
       begin
         if not WideInputQuery('RegEx didn''t match the full filename.', 'Old filename:'+#10+FileName+#10+#10+'Proposed new filename: '+#10+TempFileName+WideExtractFileExt(FileName)+#10+#10+'What should we do?'#10+#10+'Pressing OK button = Rename that file'+#10+'Pressing Cancek button = Skip that file'+#10+'Type '''+BREAK_STRING+''' in the text field to exit the script or '''+FOR_ALL_STRING+''' if you want to continue with all the files.'+#10, Answer) then
           exit
         else if WideSameText(WideLowerCase(Answer),BREAK_STRING) then 
           begin
             TimeToExit:=True;
             exit;
           end
         else if WideSameText(WideLowerCase(Answer),FOR_ALL_STRING) then 
           begin
             CheckIfFullMatch:=False;
           end
         else
           Answer:=STANDARD_ANSWER;
       end;
   

  if SKIP_EXTENTION then   
    FileName:=TempFileName+WideExtractFileExt(FileName)
  else FileName:=TempFileName;
  

end
else exit;
 
end.

Enjoy! big_smile

Last edited by krtek (2009-08-12 11:31)


Regular Expressions are not as hard to understand as you may think. Check ReNamer's manual or nice Regular Expressions tutorial for more info and start to use full power of applications that use them (like ReNamer, Mp3Tag and so on).

Offline

Board footer

Powered by FluxBB