繁体   English   中英

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

[英]Need help to create regular expression in Java

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

例如此处: *..***...**...****....*....*****..**

我们有4倍*和7倍**

这就是我已经拥有的:


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

在输出上我有5x *和5x **这是什么问题。

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

\\*\\*|\\*

因为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})+)\\\\*(\\\\.|$)只接受一个*

  • ^
  • .
  • 甚至*

在此之前,以及

  • .
  • $

之后。

只要*前面有*偶数,就接受*策略. $在它有一个缺陷之后,因为

****.
 ^^^^

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

这就是为什么此正则表达式匹配标有^#数据(其中标有#数据不应该存在)的原因:

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

并且您看到5匹配项。

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

*.*.
^^

首先*. 将被匹配,但是. 将包含在此匹配项中,以防止正则表达式在测试第二个*.使用它*. 因为第二*. 不能包含first . (在先前的比赛中使用)在其比赛正则表达式中是不正确的,因为*没有^(\\\\*{2})+)或可以自由使用. 在它之前。

所以甚至在现实中. 不应该包含在比赛中

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

为了摆脱这些问题,您可以使用环顾四周机制并将您的正则表达式更改为类似

"(?<=^|\\.)(\\*{2})*\\*(?=\\.|$)"

这个正则表达式将发现

  • *(\\\\*{2})*\\\\* )的奇数
  • 如果他们有
    • 字符串或的开始. 在它之前(?<=^|\\\\.)
    • . 或后面的字符串结尾(?=\\\\.|$)

twoStarsPattern

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

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

*..***...**...****....*....*****..**
  ^^^^  ^^^^ ^^^^         ^^^^   ^^^

每次比赛都有问题,因为

  • 再次包括.
  • 但这一次在末尾还包含其他* ,以防止下一场比赛使用它
  • 此正则表达式(^|\\\\.|(\\\\*{2})+)\\\\*{2}将搜索最大可能的星号偶数(因为(\\\\*{2})+ ),而不是一对

这个正则表达式是过度复杂化的很好的例子。 似乎比第一个更难修复,但实际上它很简单。
您只需要使用\\\\*\\\\*正则表达式即可。 它将仅匹配一对星号,返回它们中的每一个并寻找下一个。 此正则表达式很安全,因为您不能重复使用已经匹配的** ,所以它将匹配

*********
11223344x

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM