Phoenix
Phoenix

Reputation: 8923

Why doesn't the following regex work when input through Spring

Here is the spring configuration:

<bean id="wrapInMarginalMarkup" class="com.a.ChangeContentAction">
        <property name="regEx">
            <bean class="java.util.regex.Pattern" factory-method="compile">
                <constructor-arg value="(.*)(&lt;m&gt;)(.*)(&lt;xm&gt;)(.*)" />
            </bean>
        </property>
        <property name="replaceExpression" value="$1&lt;marginal\.markup&gt;$3&lt;/marginal\.markup&gt;$5" />
    </bean>

The class accepts parameters in java like:

   private Pattern regEx;
    private String replaceExpression;

    /**
     * {@inheritDoc}
     */
    @Override
    public int execute(final BuilderContext context, final Paragraph paragraph)
    {
        String content = paragraph.getContent();
        paragraph.setContent(regEx.matcher(content).replaceAll(replaceExpression));
    }

This is what the string looks like that will be matched on the pattern:

"Be it enacted by the Senate and House of Representatives of the United States of America in Congress assembled,,&lt;m&gt;Surface Transportation Extension Act of 2012.,&lt;xm&gt;"

It doesn't seem to actually replace the markup here, what is the issue ?

I want the output string to look like:

"Be it enacted by the Senate and House of Representatives of the United States of America in Congress assembled,,&lt;marginal.markup&gt;Surface Transportation Extension Act of 2012.,&lt;/marginal.markup&gt;"

Upvotes: 1

Views: 1226

Answers (2)

Amith Perera
Amith Perera

Reputation: 11

Try to parse the Reg Ex via a property file and then create pattern object. I sorted out the same issue I faced while injecting Reg Ex via XML beans.

Ex :- I needed to parse the Reg Ex (.*)(D[0-9]{7}\.D[0-9]{9}\.D[A-Z]{3}[0-9]{4})(.*) by injecting in Spring. But it didn't work. Then I tried to use the same Reg Ex hard coded in a Java class and it worked.

Pattern pattern = Pattern.compile("(.*)(D[0-9]{7}\\.D[0-9]{9}\\.D[A-Z]{2}[0-9]{4})(.*)");
Matcher matcher = pattern.matcher(file.getName().trim());

Next I tried to load that Reg Ex via property file while injecting it. It worked fine.

p:remoteDirectory="${rawDailyReport.remote.download.dir}"
p:localDirectory="${rawDailyReport.local.valid.dir}"
p:redEx="${rawDailyReport.download.regex}"

And in the property file the property is defined as follows.

(.*)(D[0-9]{7}\\.D[0-9]{9}\\.D[A-Z]{2}[0-9]{4})(.*)

This is because the values with place holders are loaded through org.springframework.beans.factory.config.PropertyPlaceholderConfigurer and it handles these XML sensitive characters internally.

Upvotes: 1

JB Nizet
JB Nizet

Reputation: 691685

Since you're using escape entities in your Spring XML file, the actual pattern that is passed to the compile() method is not

(.*)(&lt;m&gt;)(.*)(&lt;xm&gt;)(.*)

but

(.*)(<m>)(.*)(<xm>)(.*)

If you want to pass the first pattern, you'll have to escape the ampersand:

(.*)(&amp;lt;m&amp;gt;)(.*)(&amp;lt;xm&amp;gt;)(.*)

Upvotes: 3

Related Questions