Java正则表达式匹配太多

时间:2014-08-13 00:57:56

标签: java regex parsing

所以我正在写一个国际象棋PGN解析器,而且我在分解文件时遇到了麻烦。以下是一些注意事项:

我将整个文件啜饮成一个字符串,所以我看起来像:

[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))";

我认为让我搞砸的部分是'.*'表达我使用捕捉游戏动作。我还没有为这部分提出一个不错的模式,所以我只想捕捉一个字符串中的游戏动作并继续下一个模式。

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

1 个答案:

答案 0 :(得分:1)

您需要使用Pattern.compile(PGN_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)得分本身,标题会被忽略。

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