需要帮助在Java中创建正则表达式

时间:2014-03-09 11:24:37

标签: java regex

如果有人帮我创建正则表达式以查找String中的所有***条目,我将非常感激。因为我不知道如何建立这个正则表达式。在字符串中,我们只能*.

例如: *..***...**...****....*....*****..**

我们有4x *和7x **

这就是我已经拥有的:


Pattern oneStarPattern = Pattern.compile("(^|\\.|(\\*{2})+)\\*(\\.|$)");
Pattern twoStarsPattern = Pattern.compile("(^|\\.|(\\*{2})+)\\*{2}(\\.|\\*|$)");

在输出中,我有5x *和5x **错误。

1 个答案:

答案 0 :(得分:1)

在我解释你做错了什么以及如何纠正它之前,这是一个非常简单的方法,你可以用一个正则表达式来解决你的问题。想法是让正则表达式尝试匹配第一个**,如果这不可能,那么尝试仅匹配*。这样的正则表达式看起来像

\\*\\*|\\*

因为匹配器从左到右测试OR的选项,所以在数据类似

的情况下
***

匹配器会首先尝试找到\\*\\*的匹配项,但它会成功,因此会消耗前两个星号**

***
^^

此匹配器将继续前进并再次尝试检查此处是否可以匹配\\*\\*,但由于此时只有一个*\\*\\*将无法匹配所以匹配器会尝试测试正则表达式\\*中的其他选项。所以这次匹配器只返回一个*

***
  ^

等等。

此类应用程序的代码可能类似于

String data = "*..***...**...****....*....*****..**";

Pattern p = Pattern.compile("\\*\\*|\\*");
Matcher m = p.matcher(data);

int tmp1 = 0, tmp2 = 0;
while (m.find()) {
    if (m.group().length() == 1)//found *
        tmp1++;
    else                        //found **
        tmp2++;
}
System.out.println(tmp1);
System.out.println(tmp2);

输出:

4
7

现在让我们关注你当前的正则表达式。

oneStarPattern问题

您的第一个正则表达式(^|\\.|(\\*{2})+)\\*(\\.|$)只接受一个{/ 1}}

  • *
  • ^
  • 或偶数.

之前,

  • *
  • .

之后。

接受$的策略,只要它有*个偶数*.$之后有一个缺陷,因为以防万一

****.
 ^^^^

标有^的部分也将匹配(但不应该匹配)。

这就是为什么这个正则表达式匹配标有^#标记#的数据的原因不应该在那里:

*..***...**...****....*....*****..**
^^ ^^^^        ####  ^^^   ^^^^^^   

您看到5次匹配。

另一个可能的问题是你的正则表达式会消耗周围的元素,因此在下次尝试查找下一个匹配时不能重用它们,所以在

的情况下
*.*.
^^

第一个*.将匹配,但.将包含在此匹配中,这会阻止正则表达式在测试第二个*.时使用它。由于第二个*.无法在其匹配中包含第一个.(在之前的匹配中使用),因此正则表达式将不正确,因为*没有^,{{1} },或者在它之前免费使用(\\*{2})+)

所以实际上即使.也不应该包含在匹配

.

溶液

要解决这些问题,您可以使用look-around机制并将正则表达式更改为

*..***...**...****....*....*****..**
^# ^^^#        ####  #^#   ^^^^^#   

这个正则表达式会找到

  • 只有奇数"(?<=^|\\.)(\\*{2})*\\*(?=\\.|$)" *
  • 如果有的话
    • 字符串的开头或(\\*{2})*\\*之前的.
    • (?<=^|\\.)或其后的字符串结尾.

twoStarsPattern

(?=\\.|$)

这个正则表达式与第一个类似的问题。让我们看看它目前匹配的是什么

(^|\\.|(\\*{2})+)\\*{2}(\\.|\\*|$)

每场比赛都有问题,因为

  • 再次包括*..***...**...****....*....*****..** ^^^^ ^^^^ ^^^^ ^^^^ ^^^
  • 但这次最后还包含了额外的.,阻止了下一场比赛的使用
  • 此正则表达式*将搜索最大可能偶数个星号(因为(^|\\.|(\\*{2})+)\\*{2}),而不是一对

溶液

这个正则表达式是过度复杂化事物的一个很好的例子。修复它似乎比第一个更难,但实际上它很简单 您只需要使用(\\*{2})+正则表达式。它只匹配星号对,返回每个星号并寻找下一个星号。此正则表达式是安全的,因为您无法重复使用已匹配的\\*\\*,因此它将匹配

**

其中********* 11223344x 1 2 3表示在每次匹配迭代中返回的内容,与4对应的*不会完全匹配。