代码之家  ›  专栏  ›  技术社区  ›  Carl

Java扫描器头痛

  •  1
  • Carl  · 技术社区  · 15 年前

    我有一个文本文件,看起来像:

    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
    

    i、 例如,一个纯文本标签,后跟几行,1/0之间用空格分隔。1/0的行数是可变的,但任何两个特定标签之间的每一行应具有相同的1/0数(尽管可能不是)。

    我认为可能有一种使用智能分隔符规范的方便方法,但我似乎无法实现这一点。

    3 回复  |  直到 14 年前
        1
  •  1
  •   jprete    15 年前

    我会用简单的方法来做。抓住每一行作为一个整体 String ,并通过一个匹配1或0后跟空格模式的正则表达式将其输入。如果匹配,则将其视为一行。如果不是,请将其视为纯文本标签。通过检查每个标签的数据数组是否与第一个标签的数据数组的大小匹配,检查事实发生后的行-列大小一致性。

    Scanner 上课,虽然听起来很方便。我认为基本的想法应该仍然大致相同…使用 解析您的输入,并自行处理大小问题。

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

        2
  •  1
  •   Community CDub    8 年前

    helpful answer to another question (谢谢 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;
    }
    
        3
  •  0
  •   user152759 user152759    15 年前

    --我假设您在遍历文件时正在执行一致性。如果您想存储这些信息并在以后使用它,我会考虑使用某种类型的数据结构。

    在遍历该行时,可以使用简单的正则表达式检查该行是否为标签名。如果没有,请根据“”分割行(空格字符),它将以数组形式返回给您。然后根据一致的大小检查大小。

    基本伪码:

    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");
        }
    }