Solved

How to use Preg_match to get string that continues on next line

Posted on 2012-03-16
15
732 Views
Last Modified: 2013-12-13
Hello all again.

I was given help on a topic earlier that gave the following:

if(preg_match[b]("/(~TRN\*[^\*]+\*[^\*]+)[/b]/",file_get_contents($oldfile),$matches))
	 {
	 // Match found! Renaming file!
     $newfile = str_replace(array(".txt","*"),array("_","-"),$oldfile.$matches[0]).".txt";
     echo "Renaming file from {$oldfile} to {$newfile}...". "<br /> <br />";
     }
     else
     {
     // No match found!
     }
     }

Open in new window



Thank you again gr8gonzo on the help. The code works great until it come across string that wraps to the nextline.
example:
89245*000087726*01*052000113*DA*18790741*20120312~T
RN*1*1QG70794930
*1411289245*000087726

I tried to play with regular expressions and was unable to get the Part in bold to work when the line wraps or carriage returns.  I also tried doing
echo substr($str,124,11) . "<br /> <br />"; but even though that gave me what I was looking for in the case above it fail for other files.

NON************20120312~T
RN*1*1QG70795851
*1411289245*  

I could not find any sites that explicitly showed how to use the regular expressions.  

Thanks for any help with this.
0
Comment
Question by:Sqlspider
  • 5
  • 5
  • 2
  • +1
15 Comments
 
LVL 9

Expert Comment

by:Shaun McNicholas
ID: 37730762
If you are looking for the regular expression syntax for finding carriage returns I believe its \r
0
 
LVL 9

Expert Comment

by:Shaun McNicholas
ID: 37730779
So replace the replacement line with this.

$newfile = str_replace(array(".txt","*","\r","\n"),array("_","-","",""),$oldfile.$matches[0]).".txt";

That will replace any carriage returns with nothing (or delete them)
And \n for New Line gets replaced with nothing as well.
0
 

Author Comment

by:Sqlspider
ID: 37730836
Ok I understand you comment but the problem is with preg_match.  for example.
If i take the text
89245*000087726*01*052000113*DA*18790741*20120312~T
RN*1*1QG70794930*1411289245*000087726

Open in new window


preg_match ("/(~TRN\*[^\*]+\*[^\*]+)/") will not grab ~T and then pick up the rest of the pattern.

If the text is the following:
89245*000087726*01*052000113*DA*18790741*20120312
~TRN*1*1QG70794930*1411289245*000087726

Preg_match ("/(~TRN\*[^\*]+\*[^\*]+)/") captures the pattern just fine.
0
 
LVL 9

Expert Comment

by:Shaun McNicholas
ID: 37730911
Well then just do a replace function on the $oldfile before doing the preg_match check
Like this

$fileContents = file_get_contents($oldfile);
$fileContents = str_replace(array("\r","\n"),array("","");

if(preg_match[b]("/(~TRN\*[^\*]+\*[^\*]+)[/b]/",$fileContents,$matches))
	 {
	 // Match found! Renaming file!
     $newfile = str_replace(array(".txt","*"),array("_","-"),$oldfile.$matches[0]).".txt";
     echo "Renaming file from {$oldfile} to {$newfile}...". "<br /> <br />";
     }
     else
     {
     // No match found!
     }
     }

Open in new window

0
 

Author Comment

by:Sqlspider
ID: 37731095
Ok I tried that and I get this

Parse error: syntax error, unexpected ';'
for this section of the code
$fileContents = str_replace(array("\r","\n"),array("","");

Yes I do like the way you put it but not sure why it is not working.
0
 
LVL 9

Expert Comment

by:Shaun McNicholas
ID: 37731131
Sorry about that its missing a closing ) in the line!


$fileContents = str_replace(array("\r","\n"),array("",""));
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:Sqlspider
ID: 37739575
Ok I tried what was stated maestropsm but maybe I am missing something. I was successful with the following until I hit another issue.

// Get an array of all files in the current directory that end in .txt
	 $txtfiles = glob("c:\splitting\*.txt"); 

	 // Loop through the files
	 foreach($txtfiles as $oldfile)
	 {
	 // Skip files that already look like they've been processed
	 if(strpos($oldfile,"_~")) continue;
	 
	 // Otherwise, process the rest of the files
	 $fileContents = file_get_contents($oldfile);
	 
	 
     if(preg_match("/((~TR|N)\*[^\*]+\*[^\*]+)/",$fileContents,$matches))
	 {
	 // Match found! Renaming file!
     $newfile = str_replace(array(".txt",""),array("_","_"),$oldfile.$matches[1]).".txt";
     echo "Renaming file from {$oldfile} to {$newfile}...". "<br /> <br />";
	 rename($oldfile,$newfile);
     }
     else
     {
     echo 'No match found!'. "<br /> <br />";
     
     }
     }

Open in new window


The change I made was in the pre_match   if(preg_match("/((~TR|N)\*[^\*]+\*[^\*]+)/",$fileContents,$matches))

This seemed to fix a few issues but not all.

Again in the txt file I am trying to capture the pattern that matches ~TRN*1*1Q54896*.

Please note that the *1Q54896* portion can vary.  I was successful in getting the echo to show on the screen properly but when I do the rename($oldfile,$newfile) I get the following on a few files

Warning: rename(c:\splitting\ERA_uhc_batch 1 to 22_20120313_013022_S_ER073560_16.txt,c:\splitting\ERA_uhc_batch 1 to 22_20120313_013022_S_ER073560_16_N_1 _1QG80786469.txt) [function.rename]: The filename, directory name, or volume label syntax is incorrect. (code: 123)

Open in new window

. Uncertain what happened here.
0
 

Author Comment

by:Sqlspider
ID: 37744554
Any help pls on this issue.
0
 
LVL 9

Expert Comment

by:Shaun McNicholas
ID: 37744714
I'm not the worlds biggest regular expression expert but I think this might do it.

if(preg_match("/((~TRN|~TR\rN|~TR\nN|~T\rRN|~T\nRN|~\rTRN|~\nTRN)\*[^\*]+\*[^\*]+)/",$fileContents,$matches))

Replace your regular expression with the above.

In the first condition using | as an or statement - I believe this will match any of the possible iterations of the ~TRN with spaces or carriage returns in between those letters and then continue through the remainder of the expression.
0
 
LVL 12

Expert Comment

by:North2Alaska
ID: 37744729
I'm no Regex expert but doesn't the '~' need to be escaped?  '\~'
0
 
LVL 108

Accepted Solution

by:
Ray Paseur earned 400 total points
ID: 37754270
This shows how to remove the unwanted end-of-line characters.  Depending on the OS that created this string the EOL may be \r or \n or both.  After the EOL characters are removed you may find that your regex works again!  HTH, ~Ray
http://www.laprbass.com/RAY_temp_sqlspider.php
<?php // RAY_temp_sqlspider.php
error_reporting(E_ALL);
echo "<pre>";

$txt = <<<TXT
89245*000087726*01*052000113*DA*18790741*20120312~T
RN*1*1QG70794930*1411289245*000087726
TXT;

// COPY AND MUNG
$new = $txt;
$new = str_replace("\r", NULL, $new);
$new = str_replace("\n", NULL, $new);

// SHOW THE DIFFERENCES IN THE STRINGS
var_dump($txt, $new);

Open in new window

0
 

Author Closing Comment

by:Sqlspider
ID: 37755141
Thank you all for the help.  Ray_Paseur's solution is what worked.  I did have to do a bit more fine tuning but the example you gave in the str_replace is what i used to cause the text to populate on its own line.  Once I did that I used the Preg_match without the added Regex and it worked.

Again you all are Top's in my book. I am trying more and more to get as good as you all are!!!!
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 37755156
Thanks for the points and thanks for using EE!  This was a great question.  All the best, ~Ray
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Does the idea of dealing with bits scare or confuse you? Does it seem like a waste of time in an age where we all have terabytes of storage? If so, you're missing out on one of the core tools in every professional programmer's toolbox. Learn how to …
Displaying an arrayList in a listView using the default adapter is rarely the best solution. To get full control of your display data, and to be able to refresh it after editing, requires the use of a custom adapter.
The viewer will learn how to dynamically set the form action using jQuery.
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now