views:

131

answers:

3

Hi there.

I'm trying to write a bit of regex which would go through some text, written by our Editors, and apply an <acronym> tag to the first instance it finds of an abbreviation set we hold in our "Glossary of Terms".

So for this example I've used the abbreviation ITS.

1st thing I thought I'd do is setup an example with a mix of scenerios I could test against, i.e. ITS sitting with punctuation, in HTML tags & ones that we've applied this to already (in other words the script has run through this before, so no need to do again).

I'm almost there but just got stuck at the last point :-(.

Here's the regex I've got so far - <[^<|]+?>?>ITS<[^<]+?>|ITS

The Example - FROM ( EVERY ITS IN BOLD TO BE WRAPPED WITH ACRONYM ):

I want you to tag thisITS, but not this wrapped one - <acronym title="ITS" id="thisIsATest">ITS</acronym>

This is another test as I still want to update <p>ITS</p> that have other HTML tags wrapped around them.`

ITS want ones that start sentences and ones that finish ITS. ITS, and ones which are wrapped in punctuation.`

Test link: <a href="index.cfm>ITS</a>


AND I WANT THIS CHANGE TO :

I want you to tag this <acronym title="ITS">ITS</acronym>, but not this wrapped one - <acronym title="ITS">ITS</acronym>

This is another test as I still want to update <acronym title="ITS">ITS</acronym> that have other HTML tags wrapped around them.`

<acronym title="ITS">ITS</acronym> want ones that start sentences and ones that finish <acronym title="ITS">ITS</acronym>. <acronym title="ITS">ITS</acronym>, and ones which are wrapped in punctuation.

Test link: <acronym title="ITS"><a href="index.cfm>ITS</a></acronym>


Are there any Reg Ex experts out there that could help me finish this off? Any other hints tips would also be appreciated.

** UPDATE ** Don't know if this helps but this would find the only in that paragraph :

<acronym[^<]*ITS</acronym>

and this will find all the ITS :

<[^<]*>ITS<[^<]*>|ITS

What I really need is a way of combining these to say find all the ITSs but exclude those in tags.

Thanks a lot, James

P.S. This is going to be placed in a ColdFusion application if that helps anyone in specific syntax.

A: 

Oh!!! It's stripped out my HTML and I can't post more than one code example (newbie!) :-(

Hope this works (from pastebin.com) - link text

James Buckingham
A: 
szupie
Thanks for your help Szupie. I tried it in the gskinner.com's RegExr app I'm using to write this and it's not highlighting anything now.
James Buckingham
Hmm, I messed up. Also, ColdFusion doesn't support lookbehinds, so the beginning part is bad. I've edited a new pattern.
szupie
+2  A: 

Here is your basic problem: regex is not a parser. This problem has been approached many times, and there is no general purpose solution with only regex. You can fake it to a point by using lookahead, lookbehind, and some really complicated footwork, but you quickly get to the point where your expression is way to complicated to maintain.

I can suggest a couple approaches.

If you are using text that is XML compliant, you can parse the text using xmlparse() and then step through the resulting structure, applying your regex to the xmltext of each node.

Alternately, you can try replacing each tag in the text block with a placeholder, doing a replace on the resulting text, then restoring the placeholders.

Obviously, neither of these is perfect, but either, with some tweaking, may get you where you're going.

Ben Doom
Thanks Ben for the input. Really all I'm looking to do is a rule that says "wrap <acronym> around every ITS that's not inside an <acronym> already". I don't need to check every tag etc.To make things easier, although the example doesn't show it, we're only wanting this to be applied to the 1st instance in the text, not everyone so I'm hoping this isn't too complex (he says!!).Cheers,James
James Buckingham
Avoiding already-wrapped instances would probably be best done with the second method I suggested. I guess I misread or read into your post that you also needed to avoid <a href="its.cfm">text</a>, so you don't break links (and images, and linked scripts, and whatever).
Ben Doom
@Ben Doom - "This problem has been approached many times" is an understatement. "Parse HTML with regex" questions show up about every 45 minutes on SO :p
womp
@womp -- that's more or less why I stopped watching the "Regex" tag. Same old "why can't I do impossible things?" questions.
Ben Doom