2011-04-15 70 views
2

在程序中假装我的目标是尽可能多地解析字符串中出现的多个"ab"。我处理这个问题,下面的代码:模式解析Java

public static void main(String[] args) 
{ 
    final String expression = "^(\\s*ab)"; 

    Scanner scanner = new Scanner("ab abab ab"); 

    while (scanner.hasNext()) 
    { 
     String next = scanner.findWithinHorizon(expression, 0); 

     if (next == null) 
     { 
      System.out.println("FAIL"); 
      break; 
     } 
     else 
     { 
      System.out.println(next); 
     } 
    } 
} 

在表达式的开头插入符号是在每个月初读提到here不允许什么,但空白。这是为了防止像"cab""c ab"这样的内容被允许。事实上,如果发生这两种情况之一,我会期望返回null并将FAIL打印到控制台。如果我从表达式中删除脱字符,它在输入上工作得非常好,如"ab abab ab",但不能返回空值"c ab"。另一方面,如果我留下插入符号,则"c ab"将按预期返回空值,但"ab abab ab"失败。我该如何做这项工作?

编辑

我原来的职位可能已经有点模糊。我上面给出的例子是我真正问题的简单版本。模式ab是一种填充模式,我会用更有趣的东西替换,比如说email地址正则表达式或者十六进制值。

在我的应用程序中,扫描器的输入不是字符串,而是我不知道的输入流。我在循环中的目标是从输入中逐个读取一个值,并验证它们的内容匹配某种模式。如果他们这样做,那么我可以对他们做一些更有趣的事情。如果不是,那么程序终止。

在上述例子中,我希望AB ABAB AB的输入到输出:

ab 
ab 
ab 
    ab 

我期望c ab到输出:

FAIL 

和我期望ab cab到输出:

ab 
FAIL 
+0

你的目标是有点混乱。如果你想解析“ab”的出现,那么为什么“c ab”不正确?这是一个事件。你是说你想要一个只有2个字符的字符串吗? – 2011-04-15 13:02:33

+1

您能否澄清匹配标准并提供一些样本字符串与预期输出?你提到你想从字符串中解析出'ab'的多次出现,但是你说'cab'和'c ab'不应该匹配。字符串是否只包含字母组合'ab'? – 2011-04-15 13:08:32

+0

立即更新我的帖子。 – LandonSchropp 2011-04-15 13:17:33

回答

4

在你想匹配的ab第一次出现的其他线程,以便插入符的罚款。 如果你想的ab每一次出现匹配,直到另一个角色时,试试这个表达式:String expression = "\\G(\\s*ab)";

\G意味着下一场比赛应该在前面停在的位置开始。

如果我使用的是与你的代码中,我得到如下结果:

  1. 输入= “AB ABAB AB”,输出= “AB”, “AB”, “AB”, “AB”

  2. 输入= “ç AB ABAB AB”,输出= “FAIL”

  3. 输入= “AB ç ABAB AB”,输出= “AB”, “FAIL”

  4. 输入= “AB ABAB AB ç”,输出= “AB”, “AB”, “AB”, “AB”, “失败”

+0

这是很酷的托马斯。正是我需要的。再次感谢。 – LandonSchropp 2011-04-15 13:55:25

+0

更多关于[Pattern]的Javadoc的信息(http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)class – JavaJigs 2015-07-28 09:21:43

0

那么... 我觉得如果我已经得到了你的问题吧,故障是在表达

expression = "^(\\s*ab*)*$"; 
+0

顺便说一句我认为你明白,正则表达式比循环中的字符串简单解析要慢得多 – VMykyt 2011-04-15 13:04:24

+1

......而校车比法拉利慢得多,但它在高峰时段快速穿过海湾大桥。请停止重复这些关于正则表达式缓慢的歇斯底里的警告。 – 2011-04-15 17:05:34

0

:你可以用正则表达式

的一个调用做到这一点尝试以下模式。如果你在开始时总是需要一个空格,你应该使用^(\ s +)而不是^(\ s *),因为*可以是0次出现,而+意味着至少一次。

0

请注意,扫描仪中的findWithinHorizon方法适用于,发现下一个出现的由指定字符串构造的模式,而不是用于匹配整个输入。如果你写了一个匹配整个输入的正则表达式,那么它将返回输入文本,如(根据VMykyt的答案)。但是,按照我的理解,这不是你想要的。

因此,您需要单独拨打String#matches方法以确保文本前面没有空格,但如果匹配,则只需查找所有ab ocurrances。

考虑在你的代码这个微小的变化:

public static void main(String[] args) { 
    matchIt("ab abab ab"); 
    matchIt("c ab"); 
    matchIt("cab"); 
} 

private static void matchIt(String str) { 
    final String expression = "ab"; 
    System.out.println("Input: [" + str + ']'); 
    Scanner scanner = new Scanner(str); 

    if(str.matches("^\\s*ab.*$")) { 
     while (scanner.hasNext()) { 
     String next = scanner.findWithinHorizon(expression, 0); 
     if (next == null) { 
      System.out.println("FAIL"); 
      break; 
     } 
     else { 
      System.out.println(next); 
     } 
     } 
    } 
    else 
     System.out.println("FAIL"); 
} 

OUTPUT:

Input: [ab abab ab] 
ab 
ab 
ab 
ab 
=========================== 
Input: [c ab] 
FAIL 
=========================== 
Input: [cab] 
FAIL 
===========================