构建要在 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"/>
还有一个简单的 XSL 文件应用到这个测试,使用上面固定的 replace() 调用:
<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 字符串的出现。
仔细阅读本文并进行测试,发现如果$pattern 有效,但不匹配任何内容,该函数将返回$input。
让我们解构你的 $pattern 正则表达式。
-
(.*) -- 零个或多个字符:
仅此一项就可以匹配整个字符串。
-
@repository -- repository 属性的值:/home/qeebrato/Git/ddt
这与 $input 字符串中实际路径的第一部分匹配。
-
(^_) -- 这就是有趣的地方。
我认为您的意思是使用 [^_] 代替,方括号表示不是下划线的字符。
但是,带有圆括号的(^_) 转换为在$input 的开头或行首的下划线的捕获匹配,具体取决于您的模式。 replace() 函数默认为 ^ 匹配整个字符串的开头。由于$input 字符串的开头没有下划线,因此此$pattern 无法匹配——因此该函数按原样返回$input。
得到你需要的东西
你说,我想要“事件处理程序”。如果您的意思是,我想提取字符串的这一部分,这是您需要将其作为输出的replace 语句:
replace(@uri, concat(".*", @repository, "/([^_]+)_.*$"), "$1")
分解:
-
.* 匹配零个或多个字符。
-
@repository 插入该属性的字符串值:/home/qeebrato/Git/ddt
-
/,因为我们需要另一个路径分隔符。
-
([^_]+) 在圆括号中捕获,我们捕获的是+ 一个或多个[^_] 不是下划线的字符。
-
_.*$ 匹配以下下划线,然后匹配其他任何内容,直到字符串结尾。
我们用$1 替换所有这些,这是我们第一个(也是唯一一个)捕获的匹配,产生eventhandlers。
注意事项
-
您在帖子中提到您有两个变量。但是,您在 replace() 调用中使用了 @ 符号,它指定了一个属性值。
如果repository 和uri 实际上是变量(在您的XSL 中使用<xsl:variable> 元素定义)或参数(使用<xsl:param> 定义),那么您需要使用$ 而不是@。
-
如果您经常使用正则表达式,那么使用正则表达式工具可能会非常值得,例如Regex Tester(在线)、RegExr(在线)或RegexBuddy(付费应用程序;显然是由维护http://www.regular-expressions.info/ 的同一个人制作的)。
(完全披露:我已经使用 RegexBuddy 多年,但与任何这些正则表达式网站或工具开发商都没有关系)。