如何使用XSLT 3.1“替换”功能删除括号后用逗号分隔的另一个数字

问题描述 投票:3回答:4

我用逗号找到的数字多于两个,但是我的正则表达式在括号内或括号外发现数字。如何查找不在括号内的数字。

使用正则表达式

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

[String

Albemarle Paper Co.诉Moody(1975)422 US 405,425, 95 S Ct 2362

预期结果

Albemarle Paper Co.诉Moody(1975)422 US 405, 95 S 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>
regex replace xsd
4个回答
0
投票

似乎您正在使用XSLT 3.1 replace function

您可以使用

replace

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

详细信息

  • [demo of how the replace works in this case-捕获组#1(在替换模式中为(\([^()]*\))]):a $1,除()之外的任何0+字符,然后是(
  • )-或
  • [|-捕获组#2(([0-9]+,)):1个以上的数字和一个逗号]
  • $2-0+空格
  • \s*-1个以上的数字
  • [0-9]+-逗号。

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


3
投票

NOTE:现在,您已经添加了XSD标记,请注意,您不能在,中使用前瞻:“ 特别值得注意的是,完全没有锚点,例如插入号和美元,单词边界和环视。”。

XML Schema 1.1支持XML Schema regex。通过以下操作,可以确保xs:assertion匹配,而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]+)+(?![^()]*\)) 。它将发现逗号分隔的数字序列,其后没有紧跟括号的非括号字符。

如果逗号必须在第二个或多个数字之后,则将其添加:

proof

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


1
投票

尝试使用此正则表达式:updated demo

\d+(?:,\s*\d+)+,(?![^\(]*\))在这里


0
投票

如果正则表达式引擎支持Demo(*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:

See Regex Demo

打印:

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())

更新

虽然我在写这篇文章,但似乎OP确实添加了一种语言405, 425, ,该语言可能不提供过程代码。无论如何我都会留下这个答案。

© www.soinside.com 2019 - 2024. All rights reserved.