Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XSLT 2.0 regular expression replace

I have the following XML:

<t>a_35345_0_234_345_666_888</t>

I would like to replace the first occurrence of number after "_" with a fixed number 234. So the result should look like:

<t>a_234_0_234_345_666_888</t>

I have tried using the following but it does not work:

<xsl:stylesheet version="2.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <xsl:template match="/">
     <xsl:value-of select='replace(., "(.*)_\d+_(.*)", "$1_234_$2")'/>
   </xsl:template>
</xsl:stylesheet>

UPDATE

The following works for me (thanks @Chris85). Just remove the underscore and add "? to make it non greedy.

<xsl:stylesheet version="2.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <xsl:template match="/">
    <xsl:value-of select='replace(., "(.*?)_\d+(.*)", "$1_234$2")'/>

   </xsl:template>
 </xsl:stylesheet>
like image 1000
M Tracker Avatar asked Oct 20 '22 08:10

M Tracker


1 Answers

Your regex is/was greedy, the .* consumes everything until the last occurrence of the next character.

So

(.*)_\d+_(.*)

was putting

a_35345_0_234_345_666_

into $1. Then 888 was being removed and nothing went into $2.

To make it non-greedy add a ? after the .*. This tells the * to stop at the first occurrence of the next character.

Functional example:

<xsl:stylesheet version="2.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <xsl:template match="/">
    <xsl:value-of select='replace(., "(.*?)_\d+(.*)", "$1_234$2")'/>
   </xsl:template>
 </xsl:stylesheet>

Here's some more documentation on repetition and greediness, http://www.regular-expressions.info/repeat.html.

like image 183
chris85 Avatar answered Oct 22 '22 19:10

chris85