我如何解析Java中有很多变体的人类格式化和类型化文本表,如果正则表达式是答案,那么如何正确地获取行值?

我如何解析Java中有很多变体的人类格式化和类型化文本表,如果正则表达式是答案,那么如何正确地获取行值?,java,regex,Java,Regex,我必须解析各种各样的用户输入。例如: Example 1: March Morning Evening (Avg Count) (Avg Count) Birds 5.6 10.35 Mammals 2.0 3.3 Example 2: March Morning Afternoon Evening (Num) (Num) (Num) Birds 5.6 9

我必须解析各种各样的用户输入。例如:

Example 1:
March
    Morning     Evening
    (Avg Count) (Avg Count)
Birds    5.6          10.35
Mammals  2.0          3.3


Example 2:
March
    Morning   Afternoon Evening
     (Num)     (Num)     (Num)
Birds    5.6       9        10
Mammals  2.0       2.5      3.3
Reptiles 1.0       5.6      1.75

Status Avg Total: Birds 24
Concerning that numbers have dwindled since last year

Example 3:
    Early     Mid       Late 
    (Count)   (Count)   (Count)
Mammal   2.0       2.5      3.3  (Count)
Reptile 1.0    5.6      1.75  (Count)
理想情况下,用户输入应该是标准的,但事实并非如此 现在就要发生了。如果不是这样,会是什么 解析用户输入的最佳方法是什么

我目前的策略是使用Java的模式匹配器类。 我正在使用matcher.matchers()测试头的格式是否正确 是一种可能的格式。基于此,我将文本发送到一个方法,该方法使用matcher.find() 从行中获取捕获组。它将拉出行名称(例如哺乳动物)和值 从课文的第一个例子中说出2.0和3.3。然而,用户输入是如此多样, 这种方法很挑剔

举个例子,我最初是从例子中取出24只鸟 2作为捕获组,因为在文本中它包含与列相似的格式。因此,我将其更改为不允许任何文本,只允许行中的行名称。然而,现在它不能像示例那样拉出行 3,旁边有(计数)

因此,我目前的方法是,使用正则表达式检查标题格式。如果是一种格式,请拉 输出行名称和值。即使采用这种策略,我也很难找到合适的正则表达式 获取正确的行和值

matcher.find()的当前正则表达式是:

(Mammal|Reptile|Bird|Mammals|Reptiles|Birds)(^a-zA-Z-]*?[0-9])\r\n|[\r\n]
其中,捕获组1为行名称,组2为数字

所以我有两个问题:

有没有更好的方法来解决这个问题


如果没有更好的方法,那么正确的正则表达式是什么来提取行及其值呢?

您可以使用两个捕获组,其中第一个组包含行名(如Birds),第二个组使用
\G
锚重复匹配包含数字的组2

请注意,您可以使用
s?
添加可选的s,以匹配哺乳动物等

(?:^(Mammals?|Reptiles?|Birds?)|\G(?!^))\h+(\d+(?:\.\d+)?)
  • (?:
    非捕获组
    • ^
      断言字符串的开头
    • (哺乳动物?|爬行动物?|鸟类?
      捕获第1组匹配任何选项
    • |
    • \G(?!^)
      在上一次匹配结束时断言位置
  • 关闭非捕获组
  • \h+
    匹配1+水平空白字符
  • 捕获第2组
    • \d+(?:\。\d+)
      匹配1+个数字和一个可选部分以匹配小数
  • 关闭第2组
|

在爪哇

final String regex = "(?:^(Mammals?|Reptiles?|Birds?)|\\G(?!^))\\h+(\\d+(?:\\.\\d+)?)";

请注意您可以使用
\S+
创建一个广泛的匹配项,以匹配非空白字符的1+倍,而不是使用
\d+(?:\.\d+)
来匹配数字。

您的意思是这样的吗
(?:^(哺乳动物?;爬行动物?;鸟类?;哺乳动物?;爬行动物?;鸟类);\G(?!^))\h+(\d+(?:\.\d+)
用户输入是一个文本/文件(如果它的文件是什么类型的文件)@stacktome用户输入最初包含在一个文件中,然后解析该文件以获取平均计数部分,并写入数据库。我正在从数据库中读取该字符串。这会有帮助吗@第四只鸟好的,谢谢!