Page 1 of 1

SC newbie question: Loop over lines

Posted: 28 Jun 2013 10:49
by Borut
:oops: This was most probably around for hundreds of times. Sorry I can not find it, even if it is in help.

Supposing I have already read a file in a variable. Now I would like to scan over the lines and, based on the line contents, include or exclude a line from being copied into another variable (which I will later save into another file).

Can someone please post a sketch in a few lines. Needs not be runnable - just the idea/functions to be used.

Thanks a lot!

Re: SC newbie question: Loop over lines

Posted: 28 Jun 2013 10:55
by Marco
Regexmatches would do what you want, as long as you want lines matching something.
Using

Code: Select all

.*(what you want to match|or another option).*
as regex should work, as the matching are tested per line.

Re: SC newbie question: Loop over lines

Posted: 28 Jun 2013 11:26
by highend
you just need a foreach loop with <crlf> as the delimiter to parse each line.

Loop over lines - For Each Line In Lines Do

Posted: 28 Jun 2013 12:25
by Stefan
Borut wrote:Supposing I have already read a file in a variable. Now I would like to scan over the lines and, based on the line contents, include or exclude a line from being copied into another variable (which I will later save into another file).

Code: Select all

//For Each Line In LineS Do

  //collect a file content into a variable:
  $INPUT = readfile("<xydata>\xyplorer.ini");  // or nowadays just "<xyini>" 
  text $INPUT;

  //initialize the $OUT var or you get "$OUT" as literal text into the output too:
  //(this could also be used to write a header line for example)
  $OUT = "";

  //for each part (put into "$myVar") from big content (parts are separate here by line break, means "for each line"): 
  foreach( $LINE , $INPUT , "<crlf>" ){

         //search for a pattern:
         //regexmatches( string, pattern, [separator=|], [matchcase=0])
    $TMP = regexmatches( $LINE , "backup"                             );

    //if pattern matched, collect the current processed line into a new variable $OUT:
    if( $TMP !=  "" ){ $OUT = $OUT . $LINE . "<crlf>"; }

   }
   //test to see what we have collected:
   text $OUT;
 
  //write collection from $OUT to a new text file:
  //writefile(filename, data, [on_exist], [mode]) 
  //writefile( "%temp%\filename.txt", $OUT) ;


Re: SC newbie question: Loop over lines

Posted: 28 Jun 2013 12:59
by FluxTorpedoe
Indeed, regexmatches would be my approach of choice, provided the "line content" string doesn't contain too many metacharacters (e.g. .()[]\, etc ), else they must be replaced before/after. Less interesting.

Out of curiosity, what would be the advantage in this case of placing a regexmatches inside a foreach? vs e.g. (quick'n dirty example)

Code: Select all

text regexmatches($INPUT, "^[^\n]*backup[^\n]*", "");

Re: SC newbie question: Loop over lines

Posted: 28 Jun 2013 14:19
by Stefan
FluxTorpedoe wrote:Out of curiosity, what would be the advantage in this case of placing a regexmatches inside a foreach?
The foreach() construct splits the whole big $INPUT into parts, here into separate lines ($LINE).
That way the user can work on whole lines containing the pattern.... or on lines they not.
I guess it was the else part why I used foreach() instead of regexmatches() alone.
(or because I know foreach better (longer) than regexmatches ?)

Code: Select all

  $INPUT = readfile("<xydata>\xyplorer.ini");
  $OUT="";  $BAD="";
  foreach($LINE,$INPUT,"<crlf>"){
      $TMP = regexmatches($LINE, "tweak");
      if($TMP!=""){
             $OUT=$OUT.$LINE."<crlf>";
      }else{
             $BAD=$BAD.$LINE."<crlf>";}
     }
  text $OUT;  text $BAD;





Maybe regexmatches() was not the best example command to explain the foreach() loop,

since regexmatches() can do my example on its own:

Code: Select all

  $INPUT   = readfile("<xydata>\xyplorer.ini"); 
  $Matches = regexmatches( $INPUT , "^.+tweak.+$" , "<crlf>"); 
  text $Matches;


Was that your concern?

.

Re: SC newbie question: Loop over lines

Posted: 28 Jun 2013 15:19
by Marco
Ok, I dug more in literature and here's what I found. First of all, go here at page #208.
As I said before, if you simply need to transfer into a variable all the lines matching a specific criterion, then regexmatches() is ok.
However, if you want more granularity, i.e. you want to perform an action for lines matching and another action for unmatching lines, then a foreach loop is necessary, which feeds each line into a nested if-else loop. In this case regexmatches() is not necessary anymore: you have to use the Like (and his cousins) operator.

Re: SC newbie question: Loop over lines

Posted: 30 Jun 2013 07:19
by Borut
Many thanks to all of you!

Since I am an absolute zero when it comes to regexsp, I am inclined to use the other way (also because it seems I will have to do different things with different lines).

@highend - Your hint would have actually been enough. The one that asks question should better not get everything solved - helps in the long run, I think.
@Stefan - Almost the whole solution. What else should one expect from you.
@Marco - Wow! I had no idea that such books are freely available in such a way. Many thanks! This has the potential to bring me a bit above my regexsp absolute zero.

Have a nice day!

Re: SC newbie question: Loop over lines

Posted: 30 Jun 2013 07:44
by j_c_hallgren
And since it relates to regexp (although I'm not an absolete zero -- more like a 0.5?), check this out:
http://www.xyplorer.com/xyfc/viewtopic.php?f=3&t=9368

Re: SC newbie question: Loop over lines

Posted: 30 Jun 2013 10:08
by Borut
Thank you j_c! Have bookmarked the debuggex now.