【问题标题】:Groovy Regex: String Split pattern not returning same result as Matcher patternGroovy Regex:字符串拆分模式不返回与匹配器模式相同的结果
【发布时间】:2018-02-23 22:49:22
【问题描述】:

我正在尝试提取字符串中开始和结束标记之间的数据。有多个匹配项,我需要提取所有匹配项(放入数组或列表中无所谓)

我有一个限制,不能在我的设置中使用正则表达式匹配器,因此我正在考虑将string.split() 与正则表达式一起使用。

def str = "USELESS STUFF START:M A:STUFF1 B:MORE2 C:THAT3 END:M START:M A:STUFF4 B:MORE5 C:THAT6 END:M START:M A:STUFF7 B:MORE8 C:THAT9 END:M USELESS STUFF"

此模式与 Regex Matcher 一起使用,并提取开始和结束标记之间的所有匹配项。

def items = str =~ /(?s)(?<=START:M).*?(?=END:M)/

结果:

[ A:STUFF1 B:MORE2 C:THAT3, A:STUFF4 B:MORE5 C:THAT6, A:STUFF7 B:MORE8 C:THAT9 ]

但是,当我尝试在 string.split 上使用相同的模式时

def items = str.split(/(?s)(?<=START:M).*?(?=END:M)/)

它为每个匹配返回结束和开始标记本身,而不是它们之间的内容。

[无用的东西开始:M,结束:M 开始:M,结束:M 开始:M,结束:M 无用的东西]

我错过了什么,为什么拆分模式不返回与 Matcher 模式相同的组?

【问题讨论】:

  • split 在每次匹配时剪切字符串,它不会返回匹配项。如果您想要相同的结果,请使用 /START:M|END:M//.*?START:M|END:M.*?START:M|END:M.*/ 之类的模式
  • 完美,第一个有效,第二个无效,只返回最后一组,跳过前两组。继续回答问题,我会接受。

标签: regex groovy split matcher


【解决方案1】:

这种行为很好地对应了方法名称:

  • 匹配what text ?
  • 拆分by what separator?

在这种情况下,Groovy 所做的实际上是在标准 Java API 上添加了一些语法糖。线def items = str =~ /(?s)(?&lt;=START:M).*?(?=END:M)/ 是一样的

Matcher items = Pattern.compile("(?s)(?<=START:M).*?(?=END:M)").matcher(str);

此匹配器找到的组将是

 A:STUFF1 B:MORE2 C:THAT3 
 A:STUFF4 B:MORE5 C:THAT6 
 A:STUFF7 B:MORE8 C:THAT9

当 Matcher 返回匹配项时,Splitter 相反,由它们分割 - 它通过给定的正则表达式找到文本的部分并将它们视为分隔符,将它们切掉并返回剩下的内容:

START:M
//  A:STUFF1 B:MORE2 C:THAT3 is cut out since it's a separator
END:M START:M
//  A:STUFF4 B:MORE5 C:THAT6 is a separator
END:M START:M
//  A:STUFF7 B:MORE8 C:THAT9 is a separator
END:M

要实际获取STARTEND 标记之间的数据,str.split(" END:M START:M | START:M | END:M ") 可以。像indexOflastIndexOfsubstring 这样的标准 String 方法可以非常有帮助地摆脱无用的东西并只获得所需的组,只需删除第一个 START:M 之前和最后一个 END:M 之前的所有内容:

str.substring(str.indexOf("START:M ") + 8, str.lastIndexOf(" END:M"))
   .split(" END:M START:M ")

// or more groovy
str[str.indexOf("START:M ") + 8 .. str.lastIndexOf(" END:M") - 1]
   .split(" END:M START:M ")

(8是START:M的长度)

【讨论】:

  • 谢谢,晚上好,但我要接受答案,关键问题是我应该在 Split 中使用什么模式来复制 Matcher 行为
  • 我没有提到的是在开始和结束分隔符之前有一些“东西”,所以删除它们不是一个好主意,因为我最终会将“东西”添加到第一个团体。我将更新我的问题以表明垃圾,所以我猜拆分模式需要适应这一点,我可以接受作为组的一部分进来的东西,只是分开
  • 太棒了 - 请将其添加到答案中,我会接受它
猜你喜欢
  • 1970-01-01
  • 2012-08-22
  • 2022-06-10
  • 2011-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-05
  • 1970-01-01
相关资源
最近更新 更多