使用正则表达式组从控制台输入中解析多个字段

时间:2015-03-26 14:00:16

标签: java regex console console-application

我有Publication实体:

public class Publication {
    private long id;
    private String authorName;
    private Topic topic;
    private long publicationTime;
    private String header;
    private String text;
//...
}

其中Topic为枚举且已预先安装了值:

public enum Topic {
    SALE, PURCHASE, RENT, SERVICES, DATING;
}

Publication实体的规则:

  1. 作者姓名可以包含拉丁字母和数字,但第一个符号应该是一个字母。它的长度应在4到20个符号的范围内。
  2. 用户应选择一个预先安装的主题。
  3. 标题应包含10到30个符号。
  4. 文字应包含20到400个符号。
  5. 用户通过控制台工作,可以编辑出版物。

    这是用户应该使用的语法: [author name] [topic] [header] [text]

    其中字段由空格分隔。

    所以我想出了以下正则表达式:

    ([a-zA-Z]\\w{3,19}) (RENT|SALE|PURCHASE|SERVICES|DATING) ((\\w|\\W|\\s){10,30}) ((\\w|\\W|\\s){20,400})

    我正在解析为:

             Pattern pattern = Pattern.compile("above regex");
             Matcher matcher = pattern.matcher(input);
             if (matcher.find()) {
                String authorName = matcher.group(1);
                Topic topic = Topic.valueOf(matcher.group(2));
                String header = matcher.group(3);
                String text = matcher.group(4);
                //...
             }
    

    但是例如对于这样的输入它失败了:

    Alexander SALE some header This is a text for some publication
    

    因为Matcher创建了超过四个小组,所以我得到了:

    authorName=Alexander
    topic=SALE
    header=header three This is a
    text=a
    

    而不是:

    authorName=Alexander
    topic=SALE
    header=header three
    text=This is a text for some publication
    

    如何解决?

1 个答案:

答案 0 :(得分:1)

您的输入格式不明确,因此您永远不会成功解析它。您无法确定[header]的结束位置和[text]的开头位置,因为您在两个值中都允许使用空格字符。

我建议您更改为输入数据中不允许的分隔符(例如;/)。或者可能要求将标题封装在您可以搜索的内容中,例如

Alexander SALE {some header} This is a text for some publication

如果您使用了我的第二个示例,则以下模式匹配它:

"([a-zA-Z]\\w{3,19}) (RENT|SALE|PURCHASE|SERVICES|DATING) \\{((?:\\w|\\W|\\s){10,30})\\} ((\\w|\\W|\\s){20,400})"

除了添加\\{...\\}以捕获标题外,我还更正了您的模式的一部分。最初你有:

((\\w|\\W|\\s){10,30})

但这会创建两个捕获组。为避免这种情况,我将内部组添加为非捕获组,并添加了?:,如下所示:

((?:\\w|\\W|\\s){10,30})