【问题标题】:Pattern matching parser模式匹配解析器
【发布时间】:2013-02-18 18:15:07
【问题描述】:

其实我构建了一个Java代码来解析下面的文本文件:

     (FAMIX.Attribute (id: 22)
(name 'obj_I')
(parentType (ref: 11))
(declaredType (ref: 27))
(isPrivate true)
   )

   (FAMIX.Attribute (id: 38)
(name 'obj_k')
(parentType (ref: 34))
(declaredType (ref: 43))
(isPrivate true)
   )

  (FAMIX.Attribute (id: 56)
(name 'obj_K')
(parentType (ref: 46))
(declaredType (ref: 43))
(isPrivate true)
    )

  (FAMIX.Attribute (id: 73)
(name 'obj_L')
(parentType (ref: 64))
(declaredType (ref: 45))
(isPrivate true)
    )

 (FAMIX.Attribute (id: 67)
(name 'obj_G')
(parentType (ref: 64))
(declaredType (ref: 46))
(isPrivate true)
    )

 (FAMIX.Attribute (id: 93)
(name 'classD')
(parentType (ref: 85))
(declaredType (ref: 94))
(isPrivate true)
   )

  (FAMIX.Attribute (id: 99)
(name 'classC')
(parentType (ref: 86))
(declaredType(ref: 86))
(isPackage true)
    )

 (FAMIX.Attribute (id: 114)
(name 'classB')
(parentType (ref: 94))
(declaredType (ref: 11))
(isPrivate true)
    )

  (FAMIX.Attribute (id: 107)
(name 'obj_c')
(parentType (ref: 94))
(declaredType (ref: 86))
(isPrivate true)
     )

Java 代码:

// Find Attributes

Pattern p111 = Pattern.compile("FAMIX.Attribute");

Matcher m111 = p111.matcher(line);
while (m111.find()) {

    FAMIXAttribute obj = new FAMIXAttribute();              
    Pattern p222 = Pattern.compile("id:\\s*([0-9]+)");
    Matcher m222 = p222.matcher(line);

    while (m222.find()) {
        System.out.print(m222.group(1));
    }

    while ((line = br.readLine()) != null && !(line.contains("FAMIX"))) {

        Pattern p333 = Pattern.compile("name\\s*'([\\w]+)\\s*'");
        Matcher m333 = p333.matcher(line);

        while (m333.find()) {       

            System.out.print(m333.group(1));
        }

        Pattern p555 = Pattern.compile("parentType\\s*\\(ref:\\s*([0-9]+)\\)");
        Matcher m555 = p555.matcher(line);
        while (m555.find()) {
           System.out.print(m555.group(1));
        }

        Pattern p666 =   Pattern.compile("declaredType\\s*\\(ref:\\s*([0-9]+)\\)");
        Matcher m666 = p666.matcher(line);
        while (m666.find()) {
           System.out.print(m666.group(1));
        } 

    }

} // exit from finding Attribute

输出:

     ***************** Attributes *****************
       obj_k    38   34   43
       obj_L    73   64   45
       classD   93   85   94
       classB   114  94   11   

根据输出,问题在于解析器跳过一些输出(跳转)

如果问题不清楚,请告诉我,我会尽力进一步澄清。

【问题讨论】:

  • 问题是当line包含FAMIX时,你没有为下次运行保存line,因此它跳过了一些组。

标签: java regex parsing


【解决方案1】:

您忘记了检查 IsPrivate 或 IsPackage 部分的正则表达式

编辑: 几个步骤会告诉你出了什么问题 添加行的打印输出以准确查看哪些行失败以及 Pattern 如何看到它们

     // Find Attributes
                System.out.print("***"+line+"***"); 
                Pattern p111 = Pattern.compile("FAMIX.Attribute");
                Matcher m111 = p111.matcher(line);
                while (m111.find()) {

"***" 将让您了解有关 java.util 的确切开头和结尾。 有时,看起来与眼睛相同的字符对于匹配器来说是不同的。

编辑 2: 您的代码缺少外循环,其中 line 首次读取。 你是否意识到代码:

                  while ((line = br.readLine()) != null && !(line.contains("FAMIX"))) {

消耗“FAMIX.Attribute”出现的下一行?如果您在(丢失的)外部循环中再次读取,您将丢失所有其他记录。

【讨论】:

  • 我不想阅读这些信息,我只需要名称 + id + parenttype+ 声明类型
  • 还是有同样的问题。
  • 同样的问题,它仍然跳过
  • 是的,这是一个大文本文件,我正在尝试从同一个文本文件中读取许多信息
【解决方案2】:

如果您确定文件包含与指定格式完全相同的行:

  • id、name、parentType、declaredType 中的每一个都必须在一行上完全声明。即你没有这样的输入:

    (FAMIX.Attribute (id:
    38)
    (name 
    'obj_k')
    (parentType 
      (ref: 34))
    (declaredType (ref: 43))
    (isPrivate true)
    )
    

    但这是允许的:

    (FAMIX.Attribute (id: 38)
    (name 'obj_k') (parentType (ref: 34)) (declaredType (ref: 43)) (isPrivate true))
    

这是下面的修改起作用的前提条件。 此假设源自您当前的代码。

String line;

FAMIXAttribute obj = new FAMIXAttribute();
boolean isModified = false;

while ((line = br.readLine()) != null) {
    if (line.contains("FAMIX.Attribute")) {
        if (isModified) {
            // TODO: Save the previous obj

            obj = new FAMIXAttribute();
            isModified = false;
        } 
    }

    // TODO: Add the block of code to parse id here
    // TODO: Add id attribute to obj, set isModified to true

    // TODO: Add the block of code to parse other stuffs here
    // TODO: Add those attributes to obj, set isModified to true
}

if (isModified) {
    // TODO: Save the last obj
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多