2017-03-05 92 views
2

我想解析文本文件并从中获取变量。这是我用来将数据转换为字符串的代码。根据各个字段的长度拆分字符串

File file = new File(p); 
BfferedReader reader = new BufferedReader(new FileReader(file)); 

while ((line = reader.readLine()) != null) { 
    oldtext += line; 
} 
reader.close(); 

编辑:文件具有固定长度的字段名称,值的长度, 值。

例如,具有长度10字段名,后跟值的单一的数字长度,然后将值

fieldOne 5abcdefieldTwo 3abcfieldThree6abcdef 

预期输出是这两个字段名称和值存储为一个键值对

fieldOne : abcde 
fieldTwo : abc 
fieldThree : abcdef 

有没有办法写一个正则表达式模式来分割字符串?我没有搜索这个可变长度拆分,但找不到任何。

如果模式分裂是不可能的,我必须编写代码来检查循环检查字段名称,值的长度和索引拆分。

+2

你将不得不文本 '场' 为每个字段的前缀? –

回答

1

您可以使用此正则表达式来捕捉现场,长度,价值组合从输入:

(\w[\w\s]{9})(\d)(.+?(?=\w[\w\s]{9}\d|$)) 
  • (\w[\w\s]{9}) - 匹配的10
  • (\d)准确长度的字段名 - 匹配字段长度
  • (.+?(?=\w[\w\s]{9}\d|$))是一个积极的前瞻,断言我们有field:len提前或我们有行尾。

RegEx Demo

代码:

final String regex = "(\\w[\\w\\s]{9})(\\d)(.+?(?=\\w[\\w\\s]{9}\\d|$))"; 
final String string = "fieldOne 5abcdefieldTwo 3abcfieldThree6abcdef"; 

final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE); 
final Matcher matcher = pattern.matcher(string); 

while (matcher.find()) { 
    System.out.printf("Field: <%s> Len: <%d> Value: <%s>%n", 
      matcher.group(1).trim(), matcher.group(2), matcher.group(3)); 
} 
1

没有正确的表达式可以正确地为你分割这个字符串。你想要的就像伪重新语法中的[a-zA-Z]+(?group1:[0-9]+)[a-zA-Z]{\group1}。不幸的是,正常水库不提供这种行为,而各种扩展(PCRE,re2等)也不会。

事实上,您所描述的语言似乎不是regular。如果您尝试手动构建自动机,则在分析数字部分时会发现需要某种内存。我的自动机理论是生锈的,但这个事情甚至可能没有上下文。


此外,请检查您没有歧义。是否允许像position12ab导致position1 : ab或将它错误?

+0

One Correction ...我刚刚编辑了这个问题。字段名称的长度是不变的。只有值的长度不同。 – Dinesh

2

现在它可以与您编辑的问题。

使用这个表达式:

([^\d]{10})(\d)(.*?) 

Explanation

试试这个:

final String pat = "([^\\d]{10})(\\d)(.*?)"; 
final String string = "fieldOne 5abcdefieldTwo 3abcfieldThree6abcdef"; 

Pattern p = Pattern.compile(pat); 
Matcher m = p.matcher(string);   
String[] val = string.split(pat); 

int cnt=0; 
while(m.find()) 
    System.out.println(m.group(1).trim()+" : "+val[++cnt]); 

Run it

输出示例:

fieldOne : abcde 
fieldTwo : abc 
fieldThree : abcdef 
相关问题