引用正则表达式中的属性/参数

时间:2017-07-06 08:07:46

标签: regex xslt xslt-2.0

我想将两种类型的xml文件(pom.xml和描述符)连接到一个数据集中。没有共同的密钥,所以我采用两个目录并在下划线之前使用项目名称片段。

我有两个变量可供使用:

repository="/home/qeebrato/Git/ddt"
uri="file:/home/qeebrato/Git/ddt/eventhandlers_repeatlookup/src/main/resources/descriptors/eventhandlers_repeatlookup.descriptor"

我想要" eventhandlers"。

要获得此项目片段,我有

<xsl:attribute name="project"><xsl:value-of select='replace(@uri,"(.*)@repository(^_).*_(^$)","$2")'/></xsl:attribute>

我在XSLT字符串处理上看到的网页没有提到在正则表达式中使用标识符。

1 个答案:

答案 0 :(得分:1)

构建要在replace()正则表达式

中使用的字符串

replace()函数至少需要三个参数:输入字符串,要匹配的正则表达式模式和替换。

在您的样本中: *输入字符串是某个元素的uri属性。 *该模式似乎包含同一元素上repository属性的值。 *替换只是模式中的第二场比赛。

您在帖子中提到的主要问题是模式 - 您希望包含repository属性的值。为此,我们可以从他的评论中听取Martin Honnen的建议,并使用concat()构建字符串:

concat("(.*)", @repository, "(^_).*_(^$)")

解决正则表达式问题

我创建了一个简单的测试XML文档:

<?xml version="1.0" encoding="UTF-8"?>
<test repository="/home/qeebrato/Git/ddt" uri="file:/home/qeebrato/Git/ddt/eventhandlers_repeatlookup/src/main/resources/descriptors/eventhandlers_repeatlookup.descriptor"/>

使用上面修复的replace()调用来应用于此测试的简单XSL文件:

<xsl:template match="test">
    <xsl:value-of select='replace(@uri,concat("(.*)", @repository, "(^_).*_(^$)"),"$2")'/>
</xsl:template>

对这个XML运行这个XSL让我:

file:/home/qeebrato/Git/ddt/eventhandlers_repeatlookup/src/main/resources/descriptors/eventhandlers_repeatlookup.descriptor

...与uri属性的原始值相同。最终,您的replace()没有做任何事情。

来自the W3C specification

  

摘要:该函数返回xs:string,该$input是通过将$pattern的匹配给定$replacement的每个非重叠子字符串替换为$input字符串的出现而获得的

仔细阅读并测试,澄清如果$pattern有效,函数会返回$pattern,但不匹配任何内容。

让我们解构你的(.*)正则表达式。

  • @repository - 零个或多个字符:
    仅这一点就可以匹配整个字符串。
  • repository - /home/qeebrato/Git/ddt属性的值:$input
    这与(^_)字符串中实际路径的第一部分匹配。
  • [^_] - 这就是事情变得有趣的地方 我你打算使用(^_)而不是方括号,它表示一个不是下划线的字符。
    但是,带有圆括号的$input会转换为replace()开头或线的开头的下划线捕获匹配,具体取决于您的模式。 ^函数默认为$input匹配整个字符串的开头。由于$pattern字符串的开头没有下划线,因此$input无法匹配 - 因此函数按原样返回replace

获得所需

你说,我想&#34; eventhandlers&#34; 。如果你的意思是,我想提取字符串的这一部分,这里是replace(@uri, concat(".*", @repository, "/([^_]+)_.*$"), "$1") 语句,你需要将其作为输出:

.*

打破这个局面:

  • @repository匹配零个或多个字符。
  • /home/qeebrato/Git/ddt插入该属性的字符串值:/
  • ([^_]+)因为我们需要另一个路径分隔符。
  • +在圆形的parens中捕获,我们捕获的是[^_]一个或多个_.*$不是下划线的字符。
  • $1匹配以下下划线,然后匹配任何其他内容直到字符串结尾。

我们将eventhandlers替换为我们的第一个(也是唯一一个)捕获的匹配,生成@

注释

  • 您在帖子中提到您有两个变量。但是,您在replace()调用中使用repository符号,该符号指定属性值。

    如果uri<xsl:variable>实际上是变量(使用<xsl:param>元素在您的XSL中定义)或参数(使用$定义),那么您需要使用{{ 1}}而不是@

  • 如果你正常使用正则表达式,那么使用正则表达式工具可能非常值得,例如Regex Tester(在线),RegExr(在线) ),或RegexBuddy(对于付款申请;显然是由维持http://www.regular-expressions.info/的同一个人制作的)。

    (完全披露:我已使用RegexBuddy多年,但与其他任何正则表达式网站或工具开发人员没有任何关系。)