Recent

Author Topic: Regex question  (Read 8994 times)

justnewbie

  • Sr. Member
  • ****
  • Posts: 292
Regex question
« on: July 15, 2019, 07:29:07 pm »
Hi guys,

I have this text:
Code: Pascal  [Select][+][-]
  1. something retvalue -1 anything anyt=55; nothing var1=5;

By using the RegExpr, I want to get the text in this form (ie. the anything and nothing should be in a new line):
Code: Pascal  [Select][+][-]
  1. something retvalue -1
  2. anything anyt=55;
  3. nothing var1=5;

The https://regex101.com/ site gives me the good result if I write the \n\0 in the substitution field (see the attached picture).
But the Lazarus cannot handle it.

My code:
Code: Pascal  [Select][+][-]
  1. reBefore := '(anything|nothing)';
  2. reAfter := '\n\0';
  3. Memo1.Text := ReplaceRegExpr(reBefore, Memo1.Text, reAfter, true);

This code doesn't do what I need. How can I solve this?

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Regex question
« Reply #1 on: July 15, 2019, 07:35:37 pm »
replace '\n\0' with LineEnding

justnewbie

  • Sr. Member
  • ****
  • Posts: 292
Re: Regex question
« Reply #2 on: July 15, 2019, 07:41:47 pm »
replace '\n\0' with LineEnding
Do you mean
Code: Pascal  [Select][+][-]
  1. reAfter := LineEnding;
?
This doesn't work.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Regex question
« Reply #3 on: July 15, 2019, 07:49:37 pm »
Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   RegExpr;
  7.  
  8. var
  9.   s1:string='something retvalue -1 anything anyt=55; nothing var1=5;';
  10.   s2, reBefore, reAfter: String;
  11. begin
  12.   reBefore := '(anything|nothing)';
  13.   reAfter := LineEnding+'$0';
  14.   s2 := ReplaceRegExpr(reBefore, s1, reAfter, true);
  15.   WriteLn(s2);
  16.   ReadLn;
  17. end.

justnewbie

  • Sr. Member
  • ****
  • Posts: 292
Re: Regex question
« Reply #4 on: July 15, 2019, 08:09:03 pm »
Great, thank you, works!
If I may ask, why did not work the original version? >> '\n\0'
What does '$0' mean?

Also, I tried this way
Code: Pascal  [Select][+][-]
  1. reAfter := '\n$0';
and it worked as well.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Regex question
« Reply #5 on: July 15, 2019, 08:41:21 pm »
Great, thank you, works!
why did not work the original version? >> '\n\0'
It did work, but did not give what you want.

What does '$0' mean?
It refers to the text inside the brackets, in this expression it may be anything or nothing. To see it, try this change:
Code: Pascal  [Select][+][-]
  1.   reAfter := '-->$0<--';

Also, I tried this way
Code: Pascal  [Select][+][-]
  1. reAfter := '\n$0';
and it worked as well.
I just checked RegExpr code, it supports:
Code: Pascal  [Select][+][-]
  1.      't': Result := #$9;  // \t => tab (HT/TAB)
  2.      'n': Result := #$a;  // \n => newline (NL)
  3.      'r': Result := #$d;  // \r => carriage return (CR)
  4.      'f': Result := #$c;  // \f => form feed (FF)
  5.      'a': Result := #$7;  // \a => alarm (bell) (BEL)
  6.      'e': Result := #$1b; // \e => escape (ESC)
  7.      'x': begin // \x: hex char
  8.  

justnewbie

  • Sr. Member
  • ****
  • Posts: 292
Re: Regex question
« Reply #6 on: July 15, 2019, 08:47:32 pm »
Thank you for your help, engkin!  :)

justnewbie

  • Sr. Member
  • ****
  • Posts: 292
Re: Regex question
« Reply #7 on: July 16, 2019, 11:58:32 am »
Now I have a bit more complicated task.
In my example there is a loop "header" that is in 3 lines, and I need it only in 1 line.
The original text:
Code: Pascal  [Select][+][-]
  1.    string something="";
  2.    bool anything=true;
  3.    for(int i=0;
  4.    i<var1;
  5.    i++)
  6.      {
  7.       string nothing=text[i];
  8.      }
I want the for(int i=0; i<var1; i++) in 1 line.
Important: I need it in a general formula, so eg. it can be either for(int var2=x; var2<var3; var2++) or for(int var4=100; var4>=var1; var4--) and similar ...

By using this regex for\s*\([^\n]+\n[^\n]+\n[^\n]+ I can get the loop "header", but I don't know how could I get the result without those 2 \n (highlighted with orange).
Any help?
« Last Edit: July 16, 2019, 12:08:49 pm by justnewbie »

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Regex question
« Reply #8 on: July 16, 2019, 01:35:58 pm »
To remove all line endings use:
Code: Pascal  [Select][+][-]
  1.   reBefore := '([^\r\n]+)[\r\n]+';
  2.   reAfter := '$1';
  3.   s2 := ReplaceRegExpr(reBefore, s1, reAfter, true);

To remove the two line endings in a for statement:
Code: Pascal  [Select][+][-]
  1.   reBefore := '(for\s*\([^\r\n]+)[\r\n]+([^\r\n]+)[\r\n]+([^\r\n]+\))';
  2.   reAfter := '$1$2$3';
  3.   s2 := ReplaceRegExpr(reBefore, s1, reAfter, true);
« Last Edit: July 16, 2019, 01:38:02 pm by engkin »

justnewbie

  • Sr. Member
  • ****
  • Posts: 292
Re: Regex question
« Reply #9 on: July 16, 2019, 02:06:33 pm »
Thank you engkin, this is exactly what I need for!
(Soon I will have new question ...)  :)

justnewbie

  • Sr. Member
  • ****
  • Posts: 292
Re: Regex question
« Reply #10 on: July 16, 2019, 04:19:45 pm »
New issue:
I need those lines that do not start with the word 'something'.
I know what ^something does, but I need for its opposite.

Edit: maybe I figured it out:
^[^\bsomething\b].*
« Last Edit: July 16, 2019, 04:36:03 pm by justnewbie »

justnewbie

  • Sr. Member
  • ****
  • Posts: 292
Re: Regex question
« Reply #11 on: July 16, 2019, 05:09:51 pm »
Next:

I have this text:
Quote
mytext mytext hjsdgfjsh 57574 //gkgaksg
//  ztwojkgk
fjfjaf//tjtrjs
nodelete fghfgkhag //zrwjsj
ghfhfhd ://uzrutziut

I want to delete the texts in red (text after the //, together the // itself), but I don't want to delete the texts in teal.
Ie., no delete if
1./ a line starts with nodelete
or
2./ there is a colon (:) right before the //

So I want to get this:
Quote
mytext mytext hjsdgfjsh 57574

fjfjaf
nodelete fghfgkhag //zrwjsj
ghfhfhd ://uzrutziut

Update:
I found the solution for the 2. case:
(?<!:)\/\/[^\n]+[\n]+
I need to expand it with the 1. rule also.
« Last Edit: July 16, 2019, 05:50:04 pm by justnewbie »

justnewbie

  • Sr. Member
  • ****
  • Posts: 292
Re: Regex question
« Reply #12 on: July 16, 2019, 06:52:22 pm »
I found a solution:
(^(?!nodelete).*)(?<!:)\/\/[^\n]+[\n]+

It works well in the online regex tester https://regex101.com/, but Lazarus gives an error (unrecognized modifier).
Any help?

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Regex question
« Reply #13 on: July 16, 2019, 07:07:23 pm »
Probably time to consider using a different engine. For instance look for FLRE.

justnewbie

  • Sr. Member
  • ****
  • Posts: 292
Re: Regex question
« Reply #14 on: July 16, 2019, 07:31:01 pm »
Probably time to consider using a different engine. For instance look for FLRE.
What is it? I only found 'flare regular expr' in Google.
Can you provide me a link?

 

TinyPortal © 2005-2018