1

我有一个看起来像这样的文本文件:

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(尽管可能不会)。

如何使用扫描仪抓取每个名称+行块?是否有任何优雅的方法来强制行数的一致性(如果它们不一致,则提供某种反馈)?

我在想可能有一种巧妙的分隔符规范的方便方法,但我似乎无法让它工作。

4

3 回答 3

1

我会用简单的方法来做。将每一行作为 a 抓取String,并通过匹配 1-or-0-followed-by-space 模式的正则表达式来馈送它。如果匹配,则将其视为一行。如果不是,则将其视为纯文本标签。通过检查每个标签的数据数组是否与第一个标签的数据数组的大小匹配,在事后检查行列大小的一致性。

编辑:我不知道这Scanner门课,虽然听起来很方便。我认为基本思想应该仍然大致相同......使用Scanner解析您的输入,并自己处理尺寸问题。

此外,理论上,您可以生成一个匹配标签和整个数组的正则表达式,尽管我不知道您是否可以生成一个保证它只匹配每个中具有相同数量值的行集排。但是,要设置更自动化的检查,您可能需要构造第二个正则表达式,它与第一个条目的数组大小完全匹配,并将其用于所有其他条目。我认为这是一个治疗比疾病更糟糕的情况。

于 2009-10-09T17:14:00.903 回答
1

更好的是,在对另一个问题有帮助的回答之后(感谢Bart):

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;
}
于 2009-10-10T16:24:52.023 回答
0

您需要打开文件并使用 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");
    }
}

如果您不知道每行的预期大小,您还可以添加另一个循环,并放入一些逻辑以找到最常见的大小,然后找出不匹配的内容。我不确定您的一致性检查需要有多复杂。

于 2009-10-09T17:18:54.417 回答