我想将两种类型的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字符串处理上看到的网页没有提到在正则表达式中使用标识符。
答案 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()
没有做任何事情。
摘要:该函数返回
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多年,但与其他任何正则表达式网站或工具开发人员没有任何关系。)