Java正则表达式匹配太多

Java正则表达式匹配太多,java,regex,parsing,Java,Regex,Parsing,因此,我正在编写一个国际象棋解析器,而我在分解文件时遇到了问题。以下是一些注意事项: 我正在将整个文件拖入一个字符串,因此我得到的结果如下所示: [Event "Rising Stars vs Experience"] [Site "Amsterdam NED"] [Date "2010.08.22"] [Round "10"] [White "Peter Heine Nielsen"] [Black "Anish Giri"] [Result "1-0"] [ECO "E05"] [White

因此,我正在编写一个国际象棋解析器,而我在分解文件时遇到了问题。以下是一些注意事项:

我正在将整个文件拖入一个字符串,因此我得到的结果如下所示:

[Event "Rising Stars vs Experience"]
[Site "Amsterdam NED"]
[Date "2010.08.22"]
[Round "10"]
[White "Peter Heine Nielsen"]
[Black "Anish Giri"]
[Result "1-0"]
[ECO "E05"]
[WhiteElo "2700"]
[BlackElo "2672"]
[Annotator "Soltis, Andy"]
[PlyCount "113"]
[EventDate "2010.08.12"]

1. d4 Nf6 2. c4 e6 3. Nf3 d5 4. g3 Be7 5. Bg2 O-O 6. O-O dxc4 7. Qc2 a6 8. a4
Bd7 9. Qxc4 Bc6 10. Bg5 h6 11. Bxf6 Bxf6 12. Nc3 Bxf3 13. Bxf3 c6 14. Qb3 Ra7
15. Ne4 Bxd4 16. Rfd1 Qb6 17. Qd3 c5 18. e3 Be5 19. Rac1 Nc6 20. Nxc5 Rd8 21.
Nd7 Qxb2 22. Qc4 b5 23. axb5 axb5 24. Qxc6 Raxd7 {Diagram [#]} 25. Qxd7 (25.
Rxd7 Rxd7 26. Qxd7 Qxc1+) 25... Rxd7 26. Rc8+ (26. Rxd7 Qxc1+) 26... Kh7 27.
Rxd7 Kg6 28. h4 Qa3 29. Kg2 Kf6 30. Rb7 Qd6 31. Ra8 b4 32. Raa7 Qf8 33. h5 Bd6
34. Rd7 Be5 35. Rab7 Qe8 36. Bd1 Bc3 37. Bb3 Bd2 38. Kf1 Bc3 39. Ke2 Qg8 40.
Bc2 Qe8 41. f4 g5 42. hxg6 fxg6 43. e4 g5 44. e5+ Bxe5 45. Rf7+ Qxf7 46. fxe5+
Kg7 47. Rxf7+ Kxf7 48. g4 Kg7 49. Kf3 Kf7 50. Bb3 Ke7 51. Ke4 Kf7 52. Bd1 Kg7
53. Kd4 Kg6 54. Kc4 h5 55. gxh5+ Kf5 56. h6 Kg6 57. Bg4 1-0
.
.
一遍又一遍。我试图创建一个模式,在开始时解析标记,然后再解析移动文本。因此,在我上面列出的示例中,应该有13个标记,后面是第一个游戏匹配的1个游戏文本。随后的每一场比赛都是相似的

我使用的正则表达式是:

private static final String PGN_PATTERN = "(^\\[\\w+\\s+\".*\"\\])+(.*(1-0|0-1))";
我认为把我搞砸的部分是我正在使用的捕捉游戏动作的
.*
表达式。我还没有为这一部分找到一个合适的模式,所以我只想捕捉一个字符串中的游戏动作,然后进入下一个模式


有人能帮我解决这个问题吗?

您需要使用
Pattern.compile(PGN\u Pattern,Pattern.DOTALL)
启用点匹配换行符

无论如何,正则表达式不是解析这个的最佳方法

因此,在我上面列出的示例中,应该有13个标记,后面是第一个游戏匹配的1个游戏文本

但是您的正则表达式将只返回3个组:#1将包含一个标记(一个组只能包含一个值),#3将包含分数,而#2将包含许多不同的内容

如果只想跳过标记,则需要修复正则表达式:

PGN_PATTERN = "(?:^\\[\\w+\\s+\"[^\"]*\"\\]\n+)+\n*(.*?(1-0|0-1))"; 
                ^                 ^         ^    |         ^
                |                 |         |    |         |
                |                 |         |    |         -- how do you match draws?
                |                 |         |    ---- blank lines between headers and body
                |                 |         --- you need to match the lines too
                |                 ---- so it won't match all the tags at once and will be faster
                ------- we're skipping them, so (?:…)
现在
group(1)
包含带有分数的移动,
group(2)
分数本身,标题被忽略


要解析头文件,您需要更复杂的东西,而不是正则表达式。

那么为什么要在整批文件中使用正则表达式呢?我走这条路是因为我认为代码会更容易-如果您指定上面的逻辑,请随意更正<代码>应该有13个标签,后跟1个游戏文本-我个人会遵循这个逻辑,13个标签不是必需的。这个游戏有13个标签。同一文件中的其他游戏可能有更多或更少。也许你可以用一个答案和一个我可以尝试的正则表达式来回答。它实际上匹配什么?所有游戏都在一个文件中吗?如果是这样,您可能只需要将
*
s更改为
*?
s。默认情况下,
*
是贪婪的,将尽可能匹配。您还可以使用
(?:1-0 | 0-1)
将该组设置为非捕获组。我现在正在忽略绘制-我确实启用了DOTALL+1.