我有发布
实体:
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;
}
发布
实体的规则:
- 作者姓名可以包含拉丁字母和数字,但第一个符号应该是字母。其长度应在 4 到 20 个符号之间。
- 用户应选择预安装的主题之一。
- 标题应包含 10 到 30 个符号。
- 文本应包含 20 到 400 个符号。
用户通过控制台工作并可以编辑出版物。
这是用户应该使用的语法:
[作者姓名][主题][标题][文本]
其中字段之间用空格分隔。
所以我想出了以下正则表达式:
([a-zA-Z]\\w{3,19}) (出租|销售|购买|服务|约会) ((\\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
如何解决?
最佳答案
您的输入格式不明确,因此您永远无法成功解析它。您无法确定 [header]
结束位置和 [text]
开始位置,因为您在两个值中都允许使用空格字符。
我建议您更改为输入数据中不允许的分隔符(例如 ;
或 /
)。或者可能要求将 header 封装在您可以搜索的内容中,例如
Alexander SALE {some header} This is a text for some publication
If you used my second example, the following pattern then matches it:
"([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})
关于java - 使用正则表达式组解析控制台输入的多个字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29280412/