Частично сравнить 2 строки

У меня есть программа с графическим интерфейсом, в которую я вставляю пару шестнадцатеричных символов (String), нажимаю кнопку поиска и нахожу для нее код. Я импортирую все шестнадцатеричные коды, для которых у меня есть код, из файла CSV. Я хочу, чтобы если я ввожу, например: 11 D7 E2 FA, моя программа будет искать только 2-й фрагмент, x означает игнорировать: x1 x7 x2 xA, и если она находит что-то подобное в CSV, она дает мне код для этого. Это то, что у меня есть до сих пор, это находит меня только в тех случаях, когда строки совпадают.

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

Образец CSV-файла:

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

Это код, который работает для меня сейчас, хотел поделиться им. Единственная проблема, которая у меня есть сейчас, заключается в том, что я могу запустить файл jar только из файла bat, двойной щелчок не работает. Понятия не имею почему.

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

person Szász Ervin    schedule 06.04.2018    source источник


Ответы (3)


Ваша проблема больше связана с разбором каждой строки. Я бы объединил некоторые регулярные выражения:

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;

}
...

А потом просто искать в списке записей. В примере я использовал фильтрацию Apache Commons Collections:

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

Я надеюсь, что вы найдете это полезным.

person Jorge_B    schedule 06.04.2018

Вы можете использовать цепочку предикатов для сравнения четных символов из шестнадцатеричной строки и строки поиска:

// 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);

Выход:

015E36FE
005E36FF

См. также: Поиск похожих строк в массиве строк

person Community    schedule 07.04.2021

Предположим, что код объявлен как String code[2], вы должны получить то, что хотите, сделав "csvSplitBy" равным ","

или явно:

code = line.split(",");
person LuisGP    schedule 06.04.2018