views:

124

answers:

3

Hi there,

I'm struggling a bit with this regular expression and wondered if anyone was about to help me please?

What I need to do is isolate the 1st phrase inside a string which is NOT inside an HTML tag. So the examples I have at the moment are:

This is some test text about <acronym
title="Incomplete Test Syndrome"
class="CustomClass">ITS</acronym> for
the **ITS** department. Also worth
mentioning ABS as well I guess.ITS,

... and ...

This is some **ITS** test text about
<acronym title="Incomplete Test
Syndrome"
class="GOTManager">ITS</acronym> for
the ITS department. Also worth
mentioning ABS as well I guess

So in the first example I want it to ignore the wrapped ITS and give me the ITS at the end of the 1st sentence.

In the second example I want it to return the ITS at the start of the 2nd sentence.

The aim is to replace these with my own custom wrapped acronym tags in a ColdFusion application I'm writing.

Thanks a lot, James

+3  A: 

As the commentators have pointed out, regular expressions are not a good tool to work with XML/HTML-like texts. That is because being "inside" something is very hard to check for in any generality (you never know in which of these possible unlimited nesting levels you are).

For your particular examples, though, it possible to do. This heavily relies on not having any nested tags. If you do, you should seriously try a different approach.

Your examples work with

^(?:<[^<]*<[^>]*>|.)*?(ITS)

This matches the entire string up to the first occurance of ITS not in a tag (and has this in its first capturing group), but it should be easy to extract the data you need there. Only matching this instance of ITS is not possible, since your implementation of regular expressions does not support arbitrary length look-behinds.

Ask if you want/need the expression explained. =)

Jens
A: 

I will tell you the same thing I told you when you asked a very similar question: http://stackoverflow.com/questions/2675413/stuck-with-regular-expression-code-to-apply-html-tag-to-text-but-exclude-if-insid

You CANNOT parse HTML, including nested elements, with pure regular expressions. This is a known limitation of regex and is well documented.

You can try installing and using an external regular expression engine with extensions, which might work. You can manually walk the string, counting the nesting to see if the string you are looking at is wrapped. You can use a genuine HTML parser, like WebKIT do do this externally.

But you can't do it with regex. Please look for an alternative. Heck, we'll even help.

Ben Doom
A: 

You say:

The aim is to replace these with my own custom wrapped acronym tags in a ColdFusion application I'm writing.

It sounds like using XSL might be more appropriate than regex to transform one tag into another.

UPDATE:

Just threw this together, it seems to work for simple cases:

(NOTE: this will simply strip out the 'acronym' tags. You could use XSL to replace them with your own custom tags, but you didn't specify anything along those lines so I didn't get into that)

XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
 <xsl:template match="*[name() = 'acronym']" />
</xsl:stylesheet>

Input:

<?xml version="1.0" encoding="UTF-8"?>
<root>
This is some test text about <acronym
title="Incomplete Test Syndrome"
class="CustomClass">ITS</acronym> for
the **ITS** department. Also worth
mentioning ABS as well I guess.ITS,

This is some **ITS** test text about
<acronym title="Incomplete Test
Syndrome"
class="GOTManager">ITS</acronym> for
the ITS department. Also worth
mentioning ABS as well I guess
</root>

Output:

<?xml version="1.0" encoding="UTF-8"?>
This is some test text about  for
the **ITS** department. Also worth
mentioning ABS as well I guess.ITS,

This is some **ITS** test text about
 for
the ITS department. Also worth
mentioning ABS as well I guess

UPDATE:

You said:

So in the first example I want it to ignore the wrapped ITS and give me the ITS at the end of the 1st sentence.

In the second example I want it to return the ITS at the start of the 2nd sentence.

This makes no sense. Your second example doesn't have "ITS" in the second sentence. I think what you meant was that the **ITS** is what you want to have extracted.

The XSL sample I gave only strips the <acronym/> tags, but after that's done you can try to find the ITS at different points in the sentence and maybe for that a regex might be easy (this assumes that you're ONLY have to worry about the <acronym/> tags).

FrustratedWithFormsDesigner