我当前的项目围绕着将文档中的多个测试用例转换为与测试用例管理系统兼容的 XML 格式。在许多情况下,标题以许多票证标识符、文档位置编号等为前缀,在将它们上传到系统之前需要将其删除。
鉴于这些票证标识符中的许多可能存在于标题中的其他位置并且完全有效,因此我以当前形式编写了翻译,以便仅检查字符串的开头是否有正则表达式。我写了两种方法,结果各不相同。
样本输入
1.
<case-name>3.1.6 (C0) TID#EIIY CHM-2213 BZ-7043 Client side Java Upgrade R8</case-name>
2.
<case-name>4.2.7 (C1) TID#F1DR – AIP - EHD-319087 - BZ6862 - Datalink builder res...</case-name>
期望的输出
1.
<tr:summary>Client side Java Upgrade R8</tr:summary>
2.
<tr:summary>Datalink builder res...</tr:summary>
第一种方法
<xsl:template match="case-name">
<tr:summary>
<xsl:variable name="start">
<xsl:apply-templates/>
</xsl:variable>
<xsl:variable name="start" select="normalize-space($start)"/>
<xsl:variable name="noFloat" select="normalize-space(fn:remFirstRegEx($start, '^[0-9]+([.][0-9]+)*' ))"/>
<xsl:variable name="noFloatDash" select="normalize-space(fn:remFirstRegEx($noFloat, '^[\p{Pd}]' ))"/>
<xsl:variable name="noC" select="normalize-space(fn:remFirstRegEx($noFloatDash, '^\(C[0-2]\)' ))"/>
<xsl:variable name="noCDash" select="normalize-space(fn:remFirstRegEx($noC, '^[\p{Pd}]' ))"/>
<xsl:variable name="noTID" select="normalize-space(fn:remFirstRegEx($noCDash, '^(TID)(#|\p{Pd})(\w+)' ))"/>
<xsl:variable name="noTIDDash" select="normalize-space(fn:remFirstRegEx($noTID, '^[\p{Pd}]' ))"/>
<xsl:variable name="noAIP" select="normalize-space(fn:remFirstRegEx($noTIDDash, '^AIP' ))"/>
<xsl:variable name="noAIPDash" select="normalize-space(fn:remFirstRegEx($noAIP, '^[\p{Pd}]' ))"/>
<xsl:variable name="noCHM" select="normalize-space(fn:remFirstRegEx($noAIPDash, '^(CHM)[\p{Pd}]([0-9]+)' ))"/>
<xsl:variable name="noCHMDash" select="normalize-space(fn:remFirstRegEx($noCHM, '^[\p{Pd}]' ))"/>
<xsl:variable name="noEHD" select="normalize-space(fn:remFirstRegEx($noCHMDash, '^(EHD)[\p{Pd}]([0-9]+)' ))"/>
<xsl:variable name="noEHDDash" select="normalize-space(fn:remFirstRegEx($noEHD, '^[\p{Pd}]' ))"/>
<xsl:variable name="noBZ" select="normalize-space(fn:remFirstRegEx($noEHDDash, '^(BZ)(((#|\p{Pd})[0-9]+)|[0-9]+)' ))"/>
<xsl:variable name="noBZDash" select="normalize-space(fn:remFirstRegEx($noBZ, '^[\p{Pd}]' ))"/>
<xsl:variable name="noTT" select="normalize-space(fn:remFirstRegEx($noBZDash, '^(TT)[#](\w)+' ))"/>
<xsl:variable name="noTTDash" select="normalize-space(fn:remFirstRegEx($noTT, '^[\p{Pd}]' ))"/>
<xsl:variable name="nobrack" select="normalize-space(fn:remFirstRegEx($noTTDash, '^\[(.*?)\]' ))"/>
<xsl:variable name="noBrackDash" select="normalize-space(fn:remFirstRegEx($nobrack, '^[\p{Pd}]' ))"/>
<xsl:value-of select="normalize-space($noBrackDash)"/>
</tr:summary>
</xsl:template>
<xsl:function name="fn:remFirstRegEx">
<xsl:param name="inString"/>
<xsl:param name="regex"/>
<xsl:variable name="words" select="tokenize($inString, '\p{Z}')"/>
<xsl:variable name="outString">
<xsl:for-each select="$words">
<xsl:if test="not(matches(., $regex)) or index-of($words, .) > 1">
<xsl:value-of select="."/><xsl:text> </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="string-join($outString, '')">
</xsl:function>
注意:命名空间fn,为了这个翻译的目的,只是“函数/命名空间”,用来写我自己的函数。
第一个结果
1. 成功
<tr:summary>Client side Java Upgrade R8</tr:summary>
2.失败
<tr:summary>- EHD-319087 - BZ6862 - Datalink builder resolution selector may drop leading zeros on coordinate seconds</tr:summary>
第二种方法
<xsl:function name="fn:remFirstRegEx">
<xsl:param name="inString"/>
<xsl:param name="regex"/>
<xsl:analyze-string select="$inString" regex="$regex">
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:function>
这种方法完全失败了,我将它包括在这里,因为它是更明显的解决方案并且根本不起作用。
需要注意的是,上述解决方案中有大量的正则表达式,这是为了考虑到所有可能通过的ID。幸运的是,ID 的顺序似乎是一致的。
正如我所得出的结论,问题在于破折号。我注意到,在翻译失败的文档中,失败的 ID 前后都有一个破折号。如果它只是在前面,它会顺利通过。如果它只是跟随,没有问题。两者都是它掉下来的地方,奇怪的是,破折号仍然出现,尽管它似乎已经从字符串中删除了。
这里有两种破折号,普通破折号 ( –
) 和减号 ( -
)。
矛盾的是:很抱歉这个问题很长,如果我错过了什么,请告诉我。
编辑:忘了说,除破折号外的所有正则表达式都已在其他地方进行了测试,并且已知适用于所有输入内容。
编辑二:按照@acheong87的解决方案,我尝试运行以下命令:
<xsl:template match="case-name">
<tr:summary>
<xsl:variable name="regEx" select=
"'^[\s\p{Pd}]*(\d+([.]\d+)*)?[\s\p{Pd}]*(\(C[0-2]\))?([\s\p{Pd}]*(TID|AIP|CHM|EHD|BZ|TT)((#|\p{Pd}|)\w+|))*[\s\p{Pd}]*(\[.*?\])?'"/>
<xsl:analyze-string select="string(.)" regex="{$regEx}">
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</tr:summary>
</xsl:template>
撒克逊人给了我以下错误:
Error at xsl:analyze-string at line (for our purposes, 5):
XTDE1150: The regular expression must not be one that matches a zero-length string
鉴于一切都是可选的,我可以理解为什么会出现这种情况。有没有另一种运行方式不会给我这个错误?
再次感谢。