标记直到下一次出现数据

Posted

技术标签:

【中文标题】标记直到下一次出现数据【英文标题】:Tokenizing until next occurrence of data 【发布时间】:2021-11-21 01:21:57 【问题描述】:

我有一个这样的字符串:

AA 12345678910

BB 测试测试

BB 测试测试

BB 测试测试

CC 测试

AA 0897654321

BB 测试测试

CC 测试

我将如何按数据 AA 分组?顺便说一句,这只是字符串。 我可以通过定位来做到这一点,但数据 BB 是多次出现的。

是否可以标记一大块字符串。一句话:“按AA分组,直到出现另一个AA”

【问题讨论】:

那么分组的结果是什么? 像这样: 但是输入被分成几行,AA 会在一行的开头? @MartinHonnen 是的 【参考方案1】:

假设这个输入:

<input>
AA 12345678910
BB TESTTESTTEST
BB TESTTESTTEST
BB TESTTESTTEST
CC TEST
AA 0897654321
BB TESTTESTTEST
CC TEST
</input>

还有这个 XSLT

<xsl:for-each select="tokenize(input, '^AA ', 'm')">
  <xsl:if test="normalize-space()">
    <block>AA <xsl:value-of select="." /></block>
  </xsl:if>
</xsl:for-each>

我们得到两个块:

<block>AA 12345678910
BB TESTTESTTEST
BB TESTTESTTEST
BB TESTTESTTEST
CC TEST
</block><block>AA 0897654321
BB TESTTESTTEST
CC TEST
</block>

tokenize() 在分隔符处拆分输入字符串,但在处理过程中会删除分隔符。这就是为什么我们需要在输出中手动添加'AA '

【讨论】:

如果输入是:AA12345678910,代码会有什么不同吗? 'm' 是什么意思? 当您考虑一下时,您将看到针对这种情况在正则表达式中要更改的内容。 m 是多线开关。它将^(和$)的含义从“字符串的开始(结束)”更改为“行的开始(结束)”。这样,仅考虑位于行首的AA,而不是当它们随机出现在其他任何地方时。您可以使用regex101.com 来处理输入中实际存在的数据。 (对于您的下一个问题:始终按原样粘贴您的输入 XML,模糊的描述和任意更改总是会导致答案不适合您的问题。)【参考方案2】:

在 XSLT 3(自 2017 年起支持,Saxon 9.8 及更高版本、Saxon-JS 2、Altova XML 2017 R3 及更高版本)中,您可以在字符串序列上使用for-each-group group-starting-with

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:output indent="yes"/>

  <xsl:template match="data">
    <xsl:copy>
      <xsl:for-each-group select="tokenize(., '\n')[normalize-space()]" group-starting-with=".[starts-with(., 'AA')]">
        <group pos="position()">
          <xsl:apply-templates select="current-group()"/>
        </group>
      </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match=".[. instance of xs:string]">
    <xsl:element name="substring(., 1, 2)"/>
  </xsl:template>
  
</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/6qaHaS5

在 XSLT 2 中,与上述类似使用 for-each-group 的一种方法是首先将文本行转换为 XML 元素。

【讨论】:

以上是关于标记直到下一次出现数据的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 窗口函数 - 检索元素直到下一次出现值

计算事故的发生直到下一次事故

Teradata 保留价值直到下一次更改

取消当前的触摸事件,直到下一次触摸开始

派发后直到下一次渲染才反映最新状态

数据库:SUBSTRING 直到第一次出现的字符