正则表达式在java程序中没有按预期工作

oyxsuwqo  于 2021-07-03  发布在  Java
关注(0)|答案(2)|浏览(242)

我一直在写一个使用正则表达式的程序。它在文件中搜索一些文本,根据不同玩家的得分给我一个数据库。
下面是它搜索的文本示例。

ISLAMABAD UNITED 1st innings

Player              Status                        Runs  Blls  4s   6s    S/R
David Warner        lbw            b. Hassan       19    16    4    0  118.8%
Joe Burns                          b. Morkel       73   149   16    0   49.0%
Kane Wiliiamson                    b. Tahir       135   166   28    2   81.3%
Asad Shafiq         c. Rahane      b. Morkel       22    38    5    0   57.9%
Kraigg Braithwaite  c. Khan        b. Boult        24    36    5    0   66.7%
Corey Anderson                     b. Tahir        18    47    3    0   38.3%
Sarfaraz Ahmed                     b. Morkel        0     6    0    0    0.0%
Tim Southee         c. Hales       b. Morkel        0     6    0    0    0.0%
Kyle Abbbott        c. Rahane      b. Morkel       26    35    4    0   74.3%
Steven Finn         c. Hales       b. Hassan       10    45    1    0   22.2%
Yasir Shah          not out                         1    12    0    0    8.3%

 Total:  338/10       Overs:  92.1         Run Rate:  3.67     Extras:  10 

                             Day 2  10:11 AM

                                     -X-

我使用下面的正则表达式来获取不同的字段。。

((?:\/)?(?:[A-Za-z']+)?\s?(?:[A-Za-z']+)?\s?(?:[A-Za-z']+)?\s?)\s+(?:lbw)?(?:not\sout)?(?:run\sout)?\s?(?:\(((?:[A-Za-z']+)?\s?(?:['A-Za-z]+)?)\))?(?:(?:st\s)?\s?(?:((?:['A-Za-z]+)\s(?:['A-Za-z]+)?)))?(?:c(?:\.)?\s((?:(?:['A-Za-z]+)?\s(?:[A-Za-z']+)?)?(?:&)?))?\s+(?:b\.)?\s+((?:[A-Za-z']+)\s(?:[A-Za-z']+)?)?\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)

击球手姓名-第1组
影响截肢的人(如有)-第2组
影响跳动的人(如有)-第3组
抓捕者(如有)-第4组
带导叶的人员(如有)-第5组
得分-第6组
球脸-第7组
四击-第8组
六击-第9组
这是我需要提取的文本的一个例子。。。
组0包含 David Warner lbw b. Hassan 19 16 4 0 118.8% 第一组包含“大卫华纳”
此示例中不存在组2
此示例中不存在组3
此示例中不存在组4
第5组包含“哈桑”
组6包含“19”
组7包含“16”
组8包含“4”
组9包含“0”
当我在regexr或regex101上尝试这个时,它给出了组1作为 David Warner 在第一组。。。但在我的java程序中,它给出了 David . 所有结果都是一样的。我不知道为什么?
以下是我的程序代码:

Matcher bat = Pattern.compile("((?:\\/)?(?:[A-Za-z']+)?\\s?(?:[A-Za-z']+)?\\s?(?:[A-Za-z']+)?\\s?)\\s+(?:lbw)?(?:not\\sout)?(?:run\\sout)?\\s?(?:\\(((?:[A-Za-z']+)?\\s?(?:['A-Za-z]+)?)\\))?(?:(?:st\\s)?\\s?(?:((?:['A-Za-z]+)\\s(?:['A-Za-z]+)?)))?(?:c(?:\\.)?\\s((?:(?:['A-Za-z]+)?\\s(?:[A-Za-z']+)?)?(?:&)?))?\\s+(?:b\\.)?\\s+((?:[A-Za-z']+)\\s(?:[A-Za-z']+)?)?\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)").matcher(batting.group(1));        
while (bat.find()) {
    batPos++;
    Batsman a = new Batsman(bat.group(1).replace("\n", "").replace("\r", "").replace("S/R", "").replace("/R", "").trim(), batting.group(2));
    if (bat.group(0).contains("not out")) {
        a.bat(Integer.parseInt(bat.group(6)), Integer.parseInt(bat.group(7)), Integer.parseInt(bat.group(8)), Integer.parseInt(bat.group(9)), batting.group(2), false);
    } else {
        a.bat(Integer.parseInt(bat.group(6)), Integer.parseInt(bat.group(7)), Integer.parseInt(bat.group(8)), Integer.parseInt(bat.group(9)), batting.group(2), true);
    }
    if (!teams.contains(batting.group(2))) {
        teams.add(batting.group(2));
    }
    boolean f = true;
    Batsman clone = null;
    for (Batsman b1 : batted) {
        if (b1.eq(a)) {
            clone = b1;
            f = false;
            break;
        }
    }
    if (!f) {
        if (bat.group(0).contains("not out")) {
            clone.batUpdate(a.getRunScored(), a.getBallFaced(), a.getFour(), a.getSix(), false, true);

        } else {
            clone.batUpdate(a.getRunScored(), a.getBallFaced(), a.getFour(), a.getSix(), true, true);
        }
    } else {
        batted.add(a);
    }
}
1cklez4t

1cklez4t1#

所有的评论员都是对的,当然,这可能不是用正则表达式解决的典型问题。但是要回答您的问题-为什么java和regex101之间有区别让我们试着找出一些由regex引起的问题,这些问题使它变得太复杂了。下一步是找出在java中使用它是否有区别以及为什么有区别。
我试着理解你的正则表达式(同时还有蟋蟀!)提出了一个建议,可以帮助我们理解你的正则表达式是什么 should 看起来像。
第一次尝试读取,直到达到列数。我的猜测是,你应该看看交替,而不是介绍了很多组。看看这个:示例1
说明:

(                                            # group 1 start
  \/?                                        # not sure why there should be /?
  [A-Z][a-z]+                                # first name
  (?:\s(?:[A-Z]['a-z]+)+)                    # last name
)

(?:\                                         # spaces
(                                            # group 2 start
  lbw                                        #   lbw or
 |not\sout                                   #   not out or
 |(c\.|st|run\sout)                          #   group 3: c., st or run out
  \s                                         #   space
  \(?                                        #   optional (
  (\w+)                                      #   group 4: name
  \)?                                        #   optional )
))?                                          # group 2 end

(?:\s+                                       # spaces

(                                            # group 5 start
  (?:b\.\s)(\w+)                             # b. name
))?                                          # group 5 end

\s+                                          # spaces

编辑1:实际上,您的正则表达式中也缺少一个“stumpped”选项。在我身上加了这个。编辑2:stumped没有点。编辑3:完整的示例可以在示例2中找到
一些java代码来测试它:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Foo {
    public static void main(String[] args) {
        String[] examples = {
                "David Warner lbw b. Hassan 19 16 4 0 118.8%",
                "Joe Burns b. Morkel 73 149 16 0 49.0%",
                "Asad Shafiq c. Rahane b. Morkel 22 38 5 0 57.9%",
                "Yasir Shah not out 1 12 0 0 8.3%",
                "Yasir Shah st Rahane 1 12 0 0 8.3%",
                "Morne Morkel run out (Shah) 11 17 1 1 64.7%"
        };

        Pattern pattern = Pattern.compile("(\\/?[A-Z][a-z]+(?:\\s(?:[A-Z]['a-z]+)+))(?:\\s+(lbw|not\\sout|(c\\.|st|run\\sout)\\s\\(?(\\w+)\\)?))?(?:\\s+((?:b\\.\\s)(\\w+)))?\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+\\.\\d%)");
        for (String text : examples) {
            System.out.println("TEXT: " + text);
            Matcher matcher = pattern.matcher(text);
            if (matcher.matches()) {
                System.out.println("batsman: " + matcher.group(1));
                if (matcher.group(2) != null) System.out.println(matcher.group(2));
                if (matcher.group(5) != null && matcher.group(5).matches("^b.*"))
                    System.out.println("bowler: " + matcher.group(6));
                StringBuilder sb = new StringBuilder("numbers are: ");
                int[] groups = {7, 8, 9, 10, 11};
                for (int i : groups) {
                    sb.append(" " + matcher.group(i));
                }
                System.out.println(sb.toString());
                System.out.println();
            }
        }
    }
}
gab6jxml

gab6jxml2#

你的正则表达式对于这么简单的任务来说太复杂了。为了使它变得简单(或者消除它),操作一行而不是一堆文本。
为了这个,你愿意吗

String array[] = str.split("\\n");

一旦你得到了每一行,就被一个多个空格分开,比如

String parts[] = array[1].split("\\s\\s+");

然后您可以分别访问每个部分,如 Status 可以像这样访问

System.out.println("Status - " + parts[1]);

相关问题