结构化涉及串拆分

【问题】

for all the subclasses thats stats with ~ I want to separate into 2 values and then join it to tail of an Array variable called "attributes"example

 ~ public void visitMethod(org.apache.bcel.classfile.Method arg0): 4

SUB_NAME =public void visitMethod(org.apache.bcel.classfile.Method arg0)

CC=4

which I want and join it to tail of an Array variable called "attributes"

String SUB_NAME = metadata[20];

int CC =Integer.parseInt(metadata[19]);

this is the text file i am parsing

gr.spinellis.ckjm.ClassVisitor 13 2 0 14 74 34 2 14 9 0.6042 431 0.8750 1 0.7273 0.2404 0 0 31.5385
 ~ public void visitMethod(org.apache.bcel.classfile.Method arg0): 4
 ~ public void registerCoupling(String arg0): 4
 ~ public void end(): 5
 ~ public void <init>(org.apache.bcel.classfile.JavaClass arg0, gr.spinellis.ckjm.ClassMetricsContainer arg1): 1
 ~ public gr.spinellis.ckjm.ClassMetrics getMetrics(): 1
 ~ private void incRFC(String arg0, String arg1, org.apache.bcel.generic.Type[] arg2): 1
 ~ public void start(): 1
 ~ void registerMethodInvocation(String arg0, String arg1, org.apache.bcel.generic.Type[] arg2): 1
 ~ public void visitField(org.apache.bcel.classfile.Field arg0): 1
 ~ public void visitJavaClass(org.apache.bcel.classfile.JavaClass arg0): 5
 ~ void registerFieldAccess(String arg0, String arg1): 2
 ~ static String className(org.apache.bcel.generic.Type arg0): 3
 ~ public void registerCoupling(org.apache.bcel.generic.Type arg0): 1

gr.spinellis.ckjm.ClassMetricsContainer 3 1 0 4 18 0 2 3 2 0.0000 66 1.0000 0 0.0000 0.5556 0 0 20.6667
 ~ void <init>(): 1
 ~ public gr.spinellis.ckjm.ClassMetrics getMetrics(String arg0): 2
 ~ public void printMetrics(gr.spinellis.ckjm.CkjmOutputHandler arg0): 3

gr.spinellis.ckjm.MetricsFilter 7 1 0 6 30 11 2 6 5 0.6667 218 1.0000 0 0.0000 0.2000 0 0 29.8571
 ~ public static boolean isJdkIncluded(): 1
 ~ static void processClass(gr.spinellis.ckjm.ClassMetricsContainer arg0, String arg1): 3
 ~ public static void runMetrics(String[] arg0, gr.spinellis.ckjm.CkjmOutputHandler arg1): 2
 ~ public static boolean includeAll(): 2
 ~ static void <clinit>(): 1
 ~ public static void main(String[] arg0): 7
 ~ public void <init>(): 1

gr.spinellis.ckjm.PrintPlainResults 2 1 0 3 8 0 1 2 2 0.0000 24 1.0000 0 0.0000 0.6250 0 0 10.5000
 ~ public void handleClass(String arg0, gr.spinellis.ckjm.ClassMetrics arg1): 1
 ~ public void <init>(java.io.PrintStream arg0): 1

gr.spinellis.ckjm.MethodVisitor 11 2 0 21 40 0 1 21 8 0.5500 209 1.0000 1 0.9474 0.1736 0 0 17.6364
 ~ public void visitINSTANCEOF(org.apache.bcel.generic.INSTANCEOF arg0): 1
 ~ public void visitLocalVariableInstruction(org.apache.bcel.generic.LocalVariableInstruction arg0): 2
 ~ public void visitCHECKCAST(org.apache.bcel.generic.CHECKCAST arg0): 1
 ~ private boolean visitInstruction(org.apache.bcel.generic.Instruction arg0): 4
 ~ public void visitInvokeInstruction(org.apache.bcel.generic.InvokeInstruction arg0): 2
 ~ public void visitReturnInstruction(org.apache.bcel.generic.ReturnInstruction arg0): 1
 ~ public void visitArrayInstruction(org.apache.bcel.generic.ArrayInstruction arg0): 1
 ~ public void visitFieldInstruction(org.apache.bcel.generic.FieldInstruction arg0): 1
 ~ void <init>(org.apache.bcel.generic.MethodGen arg0, gr.spinellis.ckjm.ClassVisitor arg1): 1
 ~ public void start(): 5
 ~ private void updateExceptionHandlers(): 3

gr.spinellis.ckjm.CkjmOutputHandler 1 1 0 4 1 0 3 1 1 2.0000 1 0.0000 0 0.0000 1.0000 0 0 0.0000

this is my passing logic of code

  public List<Metrics> readMetricFromCSV(String fileName) {

    List<Metrics> metricsss = new ArrayList<>();

    Path pathToFile = Paths.get(fileName);
    // create an instance of BufferedReader
    // using try with resource, Java 7 feature to close resources
    try (BufferedReader br = Files.newBufferedReader(pathToFile,
    StandardCharsets.US_ASCII)) {
    // read the first line from the text file
    String line = br.readLine();
    while (line != null && !line.isEmpty()) { // loop until all lines
                                                    // are read
    String[] attributes = line.split(" "); // the file, using a  comma as the  delimiter first  18 values

    String str =  line;

    String[] arr1 = str.split("~ ");// the file, using a  comma as the  delimiter next  2 values

    String[] arr2 = arr1[1].split(": ");

    String SUB_NAME = arr2[0], CC = arr2[1];

    //   System.out.println("SUB_NAME " + SUB_NAME + ", CC Value: " + CC);                              

    Metrics valueOfMetric = createMetric(attributes+SUB_NAME+CC);

    metricsss.add(valueOfMetric); // adding metric into ArrayList

    br.readLine();
    line = br.readLine();
        }

    } catch (IOException ioe) {
        ioe.printStackTrace();
    }

【回答】

复述一下过程:过滤出含“~”的行,按“:”分成两部分,第1部分去掉“~”,命名为SUB_NAME,第2部分命名为CC。用Java硬编写太麻烦,可以用SPL实现,很简单:


A

1

=file("d:\\source.txt").import@si()

2

=A1.select(left(~,2)=="~")

3

=A2.(~.split@t(":"))

4

=A3.new(mid(~(1),3):SUB_NAME,~(2):CC)

 

A1:读取source.txt文件内容,读成单字段串构成的序列。

undefined

A2:选出含“~”的数据。

undefined

A3:将A2序列中的字符串成员按照分隔符“:”拆成成员个数为2的序列。

A4:由A3生成一个字段为SUB_NAMECC的二维表,SUB_NAME列的数据来自A3每个序列成员的第一个成员并去掉“~”,CC列的数据来自A3每个序列成员的第二个成员。

undefined

  这段代码可以方便地集成进Java,参考Java 如何调用 SPL 脚本