Szász Ervin
Szász Ervin

Reputation: 11

Partially compare 2 strings

I have a program with a GUI where I insert a couple of hexes (String), press the search button, and I find the code for it. I import the all the hexes I have a code for from a CSV file. The thing I want is that if I enter for example: 11 D7 E2 FA, my program would only search for the 2nd nibbles, x meaning ignored: x1 x7 x2 xA, and if it finds something like that in the CSV it gives me the code for it. This is what I have so far, this only finds me the cases when the strings match.

codeOutputField.setText("");
String input = hexEntryField.getText();

try {
    br = new BufferedReader(new FileReader(FIS));
    while ((line = br.readLine()) != null) {
        code = line.split(csvSplitBy);
        if (input.equals(code[0])) {
            codeOutputField.setText(code[1]);
        }
    }
}

Sample CSV:

01 5F 1E CE,0055
01 5F 13 D0,0062
01 5E 36 FE,0101
00 5E 36 FF,1002

This is the code that works for me now, wanted to share it. Only problem I have now is that I can only run the jar file from a bat file, double-click does not work. I have no idea why.

String input = hexEntryField.getText();
String[] myStringArray = input.split("");

codeOutputField.setText("");

try {
    br = new BufferedReader(new FileReader(FIS));
    while ((line = br.readLine()) != null) {
        code = line.split(csvSplitBy);
        List<String> items = Arrays.asList(code[0].split(""));
        System.out.println(items);

        if (myStringArray[1].equals(items.get(1))
                && myStringArray[4].equals(items.get(4))
                && myStringArray[7].equals(items.get(7)) 
                && myStringArray[10].equals(items.get(10))) {
            codeOutputField.setText(code[1]);
        }
    }
}

Upvotes: 1

Views: 1166

Answers (3)

user15553668
user15553668

Reputation:

You can use a chain of predicates to compare even characters from a hex string and a search string:

// assume that we have an array of hexes
String[] hexes = {"015F1ECE", "015F13D0", "015E36FE", "005E36FF"};
// user input
String search = "035D3EFA";
// conditions to check
Predicate<String> predicateChain = IntStream
        // even numbers 0, 2, 4, 6
        .range(0, 4).map(i -> i * 2)
        // compare even characters from the
        // current string and the search string
        // Stream<Predicate<String>>
        .mapToObj(i -> (Predicate<String>)
                str -> str.charAt(i) == search.charAt(i))
        // reduce a stream of predicates
        // to a single predicate chain
        .reduce(Predicate::and)
        // otherwise the condition is not met
        .orElse(p -> false);

// output the filtered array
Arrays.stream(hexes).filter(predicateChain).forEach(System.out::println);

Output:

015E36FE
005E36FF

See also: Looking for similar strings in a string array

Upvotes: 1

Jorge_B
Jorge_B

Reputation: 9872

Your problem is more about parsing each line. I would combine some regular expressions:

public class Record {
private static final Pattern HEX_VALUE = Pattern.compile("[A-F0-9][A-F0-9]");   
//...
public static Record from(String line) throws Exception {
    Record record = new Record();
    String[] parts = line.split(",");
    if (parts.length != 2) {
        throw new Exception(String.format("Bad record! : %s", line));
    }
    record.code = parts[1];
    String hexes[] = parts[0].split("\\s");
    if (hexes.length != 4) {
        throw new Exception(String.format("Bad record! : %s", line));
    }
    for (String hex: hexes) {
        if (!HEX_VALUE.matcher(hex).matches()) {
            throw new Exception(String.format("Bad record! : %s", line));
        }
    }
    record.hex1 = hexes[0];
    record.hex2 = hexes[1];
    record.hex3 = hexes[2];
    record.hex4 = hexes[3];
    return record;
}
...
@Override
public boolean equals(Object obj) {
    boolean ret = false;
    if (obj instanceof Record) {
        Record r = (Record) obj;
        ret = equalsSecondCharacter(this.hex1, r.hex1) 
                && equalsSecondCharacter(this.hex2, r.hex2) 
                && equalsSecondCharacter(this.hex3, r.hex3) 
                && equalsSecondCharacter(this.hex4, r.hex4);
    }

    return ret;

}
...

And then just search into the list of records. In the example I have used Apache Commons Collections filtering:

while((line = br.readLine()) != null) {
    records.add(Record.from(line));
}
// Check into the list
Collection<Record> filtered = 
CollectionUtils.select(records, new EqualPredicate<Record>(inputRecord));
System.out.println("Results:");
for (Record rec: filtered) {
    System.out.println(rec);
}

I hope you find it useful.

Upvotes: 1

LuisGP
LuisGP

Reputation: 431

Supposing code is declared as String code[2], you must get what you want making "csvSplitBy" equals to ","

or explicitely:

code = line.split(",");

Upvotes: 0

Related Questions