如何使用 XSLT 3.1 "replace"函数删除括号外带有逗号的另一个数字后面的数字



我发现两个以上的数字带有逗号,但我的正则表达式在括号内或括号外找到数字。如何查找不在括号内的数字。

使用的正则表达式

([0-9]+, ){2,}

字符串

雅宝纸业公司诉穆迪 (1975( 422 US405, 425, 95S Ct 2362

预期成果

雅宝纸业公司诉穆迪 (1975( 422 US405, 95S ct 2362

特别是,我的XML看起来像

<root>
<p><styled-content><italic>Agarwal v Johnson </italic>(1979) 25 C3d 932, 942, overruled on *6 other grounds in <italic>White v Ultramar, Inc.</italic> (1999) 21 C4th 563</styled-content></p>
</root>

下面是带有正则表达式和替换函数的 XSL 模板:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="root">
<xsl:copy>
<p><xsl:value-of select="replace(p/styled-content, '[0-9]+(?:, [-0-9]+)+,(?![^()]*))', '')"/></p>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

注意:现在,您添加了 XSD 标记,请注意,您不能在 XML 架构正则表达式中使用前瞻:">特别值得注意的是完全没有像插入符号和美元、单词边界和环顾之类的锚点。

XML Schema 1.1 支持xs:assertions。通过以下方法,您可以确保123, 345, 567 text匹配项,(123, 345, 567) text(123, 345, 567) 123, 345, 567 text不会:

<xs:element name="your_element">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:assertion test="not(matches($value, '.*([^()]*([0-9]+, ){2,}[^()]*).*'))"/>
<xs:assertion test="matches($value, '.*([0-9]+, ){2,}.*')"/>
</xs:restriction>
</xs:simpleType>
</xs:element>

以下答案适用于其他使用前瞻的引擎:

[0-9]+(?:, [-0-9]+)+(?![^()]*))

请参阅证据。它将查找逗号分隔的数字序列,这些数字后面没有非括号字符,直到右括号。

如果逗号必须出现在第二个或更多数字之后,只需添加它:

[0-9]+(?:, [-0-9]+)+,(?![^()]*))
^
|___ HERE

查看更新的演示

您似乎正在使用 XSLT 3.1replace函数。

您可以使用

<xsl:value-of select="replace(styled-content, '(([^()]*))|([0-9]+,)s*[0-9]+,', '$1$2')"/>

这是在这种情况下替换如何工作的演示。

  • (([^()]*))- 捕获组 #1(替换模式中的$1(:(、除)(以外的任何 0+ 字符,然后)
  • |- 或
  • ([0-9]+,)- 捕获组 #2 ($2(:1+ 位数字和一个逗号
  • s*- 0+ 空格
  • [0-9]+- 1+ 位数字
  • ,- 逗号。

替换的是组 1 和 2 的内容。

如果正则表达式引擎支持(*SKIP)(*FAIL),那么这个正则表达式可以更好地确保数字不在括号内:

(?x)                    # Verbose flag
(?:([^()]*)        # Match '( ....'
(?:d+, ){2,}      # Our regex in '( ..... )'
(?:[^()]*))        # Match  '..... )'
(*SKIP)(*FAIL)      # Fail the first alternative
|                       # Second alternative
(?:d+, ){2,}      # Our regex not enclosed in '( ... )'

查看正则表达式演示

旧解决方案

当提出正则表达式问题时,OP 应该声明所使用的语言,因为不同的 (1( 不同的语言支持正则表达式规范的不同子集,以及 (2( 根据问题的复杂性,可能需要更多时间才能完全解决问题或至少以简单的方式解决问题。

到目前为止提出的解决方案并没有完全解决确定数字是否括在括号内的问题。他们采用简化的方法查看数字后是否跟右括号,这会导致错误的结果。

解决方案是有一个正则表达式来查找两个备用的子正则表达式模式:(1( 括号内的数字和 (2( 数字,然后确定匹配的子模式,并且仅使用秒子模式中的匹配项。在这里我使用的是Python:

import re
text = """Albemarle Paper Co. v Moody (1975) 422 US 405, 425, 95 S Ct 2362 (Booboo)
Albemarle Paper Co. v Moody (1975) 422 US 405, 95 S Ct 2362
Aerotek, Inc. v Johnson Group Staffing Co. (July 30, 2013, C067652) 2013 Cal Unpub Lexis 5424:"""
r_ex = re.compile(r"""
(?:([^)]*)             # Match '( ....'
(?P<R1>(d+,s){2,})    # Our regex in capture group R1
(?:[^)]*))             # Match  '..... )'
|                           # Second alternative
(?P<R2>(d+,s){2,})    # Our regex not enclosed in '( ... )' in capture group R2
""", flags=re.X)
for m in r_ex.finditer(text):
if m.lastgroup == 'R2': # only chose second alternative matches
print(m.group())

指纹:

405, 425,

更新

在我写这篇文章的时候,OP似乎确实添加了一种语言,xsd,它可能没有提供程序代码。无论如何,无论它的价值如何,我都会留下这个答案。

相关内容

最新更新