Java 扫描器令人头疼
-
20-09-2019 - |
题
我有一个文本文件,如下所示:
name1
1 0 1 0 1
0 1 1 1 0
0 0 0 0 0
name2
1 0 1 0 1
0 0 1 1 0
0 0 0 0 1
即,一个纯文本标签后跟几行,其中 1/0 用空格分隔。1/0 的行数是可变的,但任何两个特定标签之间的每一行都应具有相同数量的 1/0(尽管可能不是)。
如何使用扫描仪抓取每个名称+行块?是否有任何优雅的方法来强制行数的一致性(并在不一致时提供某种反馈)?
我认为可能有一种巧妙的分隔符规范的便捷方法,但我似乎无法实现这一点。
解决方案 2
更好的是,经过一段时间后 对另一个问题的有用回答 (谢谢 巴特):
static final String labelRegex="^\\s*\\w+$";
static final Pattern labelPattern = Pattern.compile(labelRegex, Pattern.MULTILINE);
Matcher labelMatcher = labelPattern.matcher("");
static final String stateRegex = "([10] )+[10]\\s+";
static final String statesRegex = "("+stateRegex+")+";
static final Pattern statesPattern = Pattern.compile(statesRegex, Pattern.MULTILINE);
Matcher stateMatcher = statesPattern.matcher("");
static final String chunkRegex = "(?="+labelRegex+")";
static final Pattern chunkPattern = Pattern.compile(chunkRegex,Pattern.MULTILINE);
Scanner chunkScan;
public void setSource(File source) {
if(source!=null && source.canRead()) {
try {
chunkScan = new Scanner(new BufferedReader(new FileReader(source)));
chunkScan.useDelimiter(chunkPattern);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public Map<String, List<GraphState>> next(int n) {
Map<String,List<GraphState>> result = new LinkedHashMap<String,List<GraphState>>(n);
String chunk, rows;
int i=0;
while (chunkScan.hasNext()&&i++<n) {
chunk = chunkScan.next().trim();
labelMatcher.reset(chunk);
stateMatcher.reset(chunk);
if (labelMatcher.find()&&stateMatcher.find()) {
rows = stateMatcher.group().replace(" ", "");
result.put(labelMatcher.group(), rowsToList(rows.split("\\n")));
}
}
return result;
}
其他提示
我会做的简单方法。抓住每一行作为String
和进料通过它,说的是,1-或-O-随后逐空间图案相匹配的正则表达式。如果匹配,把它当作一行。如果没有,把它当作一个纯文本标签。通过检查该数据的每一个标签的阵列数据的第一个标签的阵列的大小相匹配检查的事实后的行 - 列大小的一致性。
编辑:我不知道该Scanner
类的,虽然听起来方便。我认为基本思想仍然应该大致相同...使用Scanner
解析您的输入,并处理大小自己的问题。
此外,在理论上,你可以制作的正则表达式将匹配标签和整个阵列,虽然我不知道你是否能产生一个将保证它仅匹配套系与相同数量的值每排。但随后,设立更多的自动检查,你可能需要构建准确的第一个条目的数组大小相匹配的第二个正规表达式,并用它为所有的人。我认为这是其中固化方法是使病更糟糕的情况。
您将需要通过与的readLine()每行打开文件,并循环,直到你遇到文件的末尾。
- 我认为你正在做的一致性,你遍历文件。如果你想存储的信息,并在以后使用它,我会考虑使用某种类型的数据结构。
当你穿越这一点,你可以检查一个简单的正则表达式的行来检查它是否是一个标签名称。如果不是这样,基于“”(空格)分开行,它会回报给你一个数组。然后检查基于一致的尺寸大小。
基本伪代码:
int consistentSize = 5; // assume you have a size in mind
while ( (line = readLine()) != EOF)
{
// check for if label, if it's a simple name, you won't really need a regex
if (line == label)
{
// not sure if you want to do any consistency checking in here
} else {
String[] currLine = line.split(' ');
bool consist = true;
// now loop through currLine and do a check if each character is a number
for (int i = 0; i < currLine.size(); i++)
{
// can't remember java function for this (isNum() I think)
if (!currLine[i].isNum) { consist = false; break; }
}
// if got past this, the row has all numbers, therefore it is ok
// could easily add another array to keep track of rows that didn't have valid numbers and suhc
if (currLine.size() < consistentSize) System.out.println("row "+j + " is inconsistent");
}
}
您也可以加入另一个循环,如果你不知道你期望每一行的大小,并把一些逻辑中找到最常见的尺寸,然后找出不匹配。我不确定你的一致性检查如何复杂,必须这样做。