首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java重复模式匹配(2)

Java重复模式匹配(2)
EN

Stack Overflow用户
提问于 2011-10-08 17:22:17
回答 2查看 1.3K关注 0票数 0

考虑以下正则表达式:

代码语言:javascript
复制
(([^\|])*\|)*([^\|]*)

这与类型的重复字符串模式匹配。

代码语言:javascript
复制
("whatever except |" |) {0 to any times} ("whatever except |" |) {1 time}

因此,它应该匹配下面的字符串,该字符串有17个子字符串(16个重复,加上最后一个是“z”)。

代码语言:javascript
复制
"abcd  | e | fg | hijk | lmnop | |   | qrs |   t| uv| w |||||x   y|  z"

实际上,RegexPal验证给定的正则表达式是否与上面的字符串匹配。

现在,我想得到每一个子串(即"abcd \x“、"e _x”、"fg _\“等),对于它们的数目、长度等等,没有事先的了解。

根据类似标题的以前的StackOverflow职位Matcherfind()方法的文档,我只需要执行以下操作

代码语言:javascript
复制
Pattern pattern = Pattern.compile(regex); // regex is the above regex
Matcher matcher = pattern.matcher(input); // input is the above string

while (matcher.find())
{
   System.out.println(matcher.group(1));
}

但是,当我这样做的时候,我只打印出两个字符串:最后一个重复的子字符串("x \\“)和一个空值;绝对不是我所期望的16个子字符串。

在运行循环之前,还应该检查匹配是否确实发生了,但我不确定是否应该使用matches()groupCount() > 0或其他条件,因为find()也会执行匹配工作,而没有执行两倍的匹配工作。

所以,质问

  1. 我怎么才能得到所有的16个重复的子串?
  2. 我怎样才能得到最后一个子字符串?
  3. 如何检查字符串是否匹配?
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-10-08 18:11:15

如果必须使用正则表达式..。

( 1)我怎样才能得到所有16个重复的子串?

见下文。当骑自行车参加比赛时,你不需要所有的东西都匹配,只需要你想要的部分。(我得到17支火柴-这是对的吗?)

2)如何获得最后一个子字符串?

将标记切换到正则表达式的开头,并允许“^”。

3)如何检查字符串是否匹配?

什么是不打比赛的资格?任何字符串都会匹配。

下面是使用正则表达式的解决方案:

代码语言:javascript
复制
String input = "abcd  | e | fg | hijk | lmnop | |   | qrs |   t| uv| w |||||x   y|  z";
int expectedSize = 17;
List<String> expected = new ArrayList<String>(Arrays.asList("abcd  ", " e ", " fg ", " hijk ", " lmnop ", " ", "   ", " qrs ", "   t", " uv", " w ", "",
    "", "", "", "x   y", "  z"));

List<String> matches = new ArrayList<String>();

// Pattern pattern = Pattern.compile("(?:\\||^)([^\\|]*)");
Pattern pattern = Pattern.compile("(?:_?\\||^)([^\\|]*?)(?=_?\\||$)"); // Edit: allows _| or | as delim

for (Matcher matcher = pattern.matcher(input); matcher.find();)
{
  matches.add(matcher.group(1));
}

for (int idx = 0, len = matches.size(); idx < len; idx++)
{
  System.out.format("[%-2d] \"%s\"%n", idx + 1, matches.get(idx));
}

assertSame(expectedSize, matches.size());
assertEquals(expected, matches);

输出

代码语言:javascript
复制
[1 ] "abcd  "
[2 ] " e "
[3 ] " fg "
[4 ] " hijk "
[5 ] " lmnop "
[6 ] " "
[7 ] "   "
[8 ] " qrs "
[9 ] "   t"
[10] " uv"
[11] " w "
[12] ""
[13] ""
[14] ""
[15] ""
[16] "x   y"
[17] "  z"
票数 1
EN

Stack Overflow用户

发布于 2011-10-08 17:33:13

恐怕你弄糊涂了。每当你使用重复('*','+‘等),你不能使所有的实例匹配。使用类似于((xxx)*)的方法,您可以将整个字符串匹配为group(1),而最后一部分匹配为group(2),其他任何部分都可以。

考虑使用String.split或更好的番石榴的分离器

广告1。你不能。使用一个简单的模式,比如

代码语言:javascript
复制
\G([^\|])*(\||$)

find()一起获得所有匹配的顺序。注意,\G锚定到以前的匹配。

广告2。我怎样才能得到最后一个子字符串?

最后一个结果是,find返回。

广告3.如何检查字符串是否匹配?

在上一次find检查是否matcher.end() == input.length之后。但是使用这种模式,您不需要检查任何东西,因为它总是匹配的。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7698499

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档