Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Andrzejek on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Reg expression help please... 2

Status
Not open for further replies.

nickroper

Programmer
Jun 1, 2004
24
GB
Hi,

I have a regular expression that converts newline characters to '<BR>'. I need to modify this so that it only converts the newline characters if they are not preceeded by certain other strings ('table>', 'td>' and 'tr>')

So, examples would be as follows:

original string:

'line1\n line2\n line3'

would be converted to:

'line1<BR> line2<BR> line3'

Whereas:

'<table>\n<tr>\<td>line1\nline2\nline3</td>\n</tr>\n</table>'

would be converted to:

'<table>\n<tr>\<td>line1<BR>line2<BR>line3</td>\n</tr>\n</table>'

My existing expression is:

$foo =~ s/\n/<BR>/g;

which converts ALL occurrences of \n. If any regex gurus out there can let me know the trick to ignore \n preceeded by 'table>', 'td>' and 'tr>' (I've left the opening bracket off in order to catch both openng and closing tags) then I'd be extremely grateful.

Cheers,

Nick Roper
 
Hi Duncan,

Great, thanks for the quick response. One question - will this ignore a linefeed preceeded by any closing tag ? I really just want to ignore table tags.

Thanks,

Nick
 
yes! i'll try to improve this to suit your needs more exactly - but i can't work it out at the moment

it's going to be necessary to use negative lookbehind assertion with alternation ... i can't seem to crack it!?


Kind Regards
Duncan
 
just had to drop the alternation...

s/(?<!table>)(?<!tr>)(?<!td>)\\n/<br>/g;


Kind Regards
Duncan
 
this should do exactly what you require


Kind Regards
Duncan
 
Duncan - you are a true star!

Just to make it more interesting, here's another tweak:

If the \n IS preceeded by 'table>', 'tr>' or 'td>' then, instead of just leaving it as a \n character, it would be better to replace it with a pseudo linefeed - say a string such as '{n}' If I leave the actual line feed in place then it messes up the text file.

So, 'foo\n bar' becomes 'foo<BR> bar' but 'foo <table>\n ' becomes 'foo <table>{n}'

Regards,

Nick
 
probably have to be done with 2 regex's

do this after the previous regex:-

s/\\n/{n}/g;


Kind Regards
Duncan
 
Nick,
It's better to give someone a star than to just tell them they are a start. Better still do both.
I thought it was a good piece of work so Dunc, have a star from me.
;-)


Trojan.
 
That makes sense.

If you can get to the George Inn at Croscombe - just outside Wells in Somerset - in the next hour or so - then the beers are on me...

If not, then I'll have one for you ;-)

Thanks again for the help.

Nick
 
Trojan,

OK, I didn't realise I could give a star - but have now done so.

By the way, the offer of the beer was to Duncan, but appears just after your post. However, the more the merrier...

Nick
 
Thanks for the offer of the beer Nick.... however, I think i might get a few points on my licence getting there in that time!!! I hope your are sorted now.


Kind Regards
Duncan
 
Surely it's worth a try though Duncs?
Good excuse for a sunday blast on the bike!
;-)


Trojan.
 
a pic of the bike...

DuncDudes_YZF750R.jpg



Kind Regards
Duncan
 
Hi Dunc,

Nice looking bike - how far away are you ?

Actually I just tried the regex. I may be something I'm doing, but it doesn't seems to work quite right and none of the \n characters are getting replaced with <BR> - even if there are no tags at all in the original input - they all remain as \n. Can you talk me through the structure of the expression?

s/(?<!table>)(?<!tr>)(?<!td>)\\n/<br>/g;

Cheers,

Nick
 
Hi Nick

That is weird!?

I am in Oxford - quite close to the city centre

I assume you are prepending with $foo =~ ...

The 3 parenthesized sections are all negative lookbehind assertions

The ?<! does this - they just mean "only replace if none of the 3 parenthesized patterns exist - immediately before the newline"


Kind Regards
Duncan
 
this works fine for me:-

Code:
[b]#!/usr/bin/perl[/b]

$foo = '<table>\n<tr>\n<td>line1\nline2\nline3</td>\n</tr>\n</table>';

print "$foo\n";

$foo =~ s/(?<!table>)(?<!tr>)(?<!td>)\\n/<br>/g;
$foo =~ s/\\n/{n}/g;

print "$foo\n";


Kind Regards
Duncan
 
Yup, I had created a very similar script, except it includes a header for the browser. I just tried yours and it works fine, but mine doesn't. I think I'm not seeing wood for trees - can you spot where I'm going wrong ?

Cheers,

Nick

=============================================
#!/usr/bin/perl

#initialise a string
$foo = "\n here is\n some text\n <table>\n<tr>";

print "Content-type: text/html\n\n";

#display unmodified string
print "$foo\n";

#display a couple of blank lines in the browser
print "\n<br><br>\n";

#modify the string
#convert non-table linefeeds to <BR>
$foo =~ s/(?<!table>)(?<!tr>)(?<!td>)\\n/<br>/g;
#now convert remaining linefeeds to '{n}'
$foo =~ s/\\n/{n}/g;

#display modified string
print $foo;

==============================================
 
Nice use of shallow depth of field Duncs.
Nice bike too.
I guess you know what R1's and GSX-R1000's look like.
I've had two of each.
Without a bike at the mo though :-(


Trojan.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top