Почему моя буферизованная строка `String` не соответствует шаблону` RegEx`? - PullRequest
0 голосов
/ 10 мая 2019

Я создал прослушиватель данных Bluetooth, который сохраняет входящие данные в String, затем проверяет, соответствует ли он шаблону регулярного выражения, а затем сбрасывает String.Это сделано потому, что данные не поступают целиком в одном экземпляре, поэтому я могу манипулировать ими, когда получаю полный текст.Например, когда я отправляю "Hello Android!" на свое устройство по Bluetooth с моим методом и распечатываю данные, это будет напечатано так:

#1 New data! "H"

#2 New data! "ello Android!

Как видите, всю строку нельзя отправить в одном экземпляре, что означает, что вместо этого отправляются две строки, и я уверен, что большинство людей знают об этом.Вот почему я использую RegEx, чтобы помочь мне в этом.

Вместо этого я посылаю случайно сгенерированное число между двумя разными символами, а затем пытаюсь их проанализировать.Например "<128>".Теперь я хочу получить целое число, чтобы я мог использовать его, например, разобрать его в int или что-то в этом роде.Но только когда мой буфер String получает все отправляемые данные, что определяется шаблоном RegEx, который выглядит как ([<])(-?\d+)([>]).character <<code>followed by any positive/negative number followed by character '>'.

Проблема в том, что он не соответствует шаблону вообще по неизвестным причинам.

String szBuffer = "";

if(mmInputStream.available() > 0) {
    StringBuilder builder = new StringBuilder();
    byte[] bData = new byte[1024];

    while(mmInputStream.available() > 0) {
        int read = mmInputStream.read(bData);
        builder.append(new String(bData, 0, read, StandardCharsets.UTF_8));
    }

    szBuffer += builder.toString();

    Log.d("SZ_BUFFER", szBuffer); // For this example, "<128>" gets sent into pieces.

    // <n>
    if(Pattern.matches("([<])(-?\\d+)([>])", szBuffer)) {
        Log.d("SZ_BUFFER_ISMATCH", "MATCH!");
        szBuffer = ""; // Reset the buffer for new data
    }
    else
        Log.d("SZ_BUFFER_ISMATCH", "NO MATCH...");
}

Вот вывод в реальном времени:

D/SZ_BUFFER: <
D/SZ_BUFFER_ISMATCH: NO MATCH...
D/SZ_BUFFER: <128>
D/SZ_BUFFER_ISMATCH: NO MATCH...

Как видите, он отправляется на две части, но когда он собирает весь текст вместе, он должен совпадать, но это не так.Зачем?Если я заменим szBuffer на постоянную String следующим образом:

if(Pattern.matches("([<])(-?\\d+)([>])", "<128>"))

Это совпадение, то есть шаблон должен быть правильным, но когда он проверяет szBuffer, он никогда не совпадает.

Ответы [ 2 ]

1 голос
/ 11 мая 2019

Проблема заключалась в том, что данные содержат невидимые символы, что было подтверждено неправильной длиной данных.Решение состоит в том, чтобы проверить каждый символ, а затем сохранить их, только если они соответствуют определенным критериям, таким как этот метод регулярного выражения:

for(char c : builder.toString().toCharArray()) {
    String s = String.valueOf(c);

    if(Pattern.matches("<|>|-|-?\\d+", s)){
        szBuffer += s;
    }
}

Это не лучшее и не самое чистое решение, но оно решает мою проблему.Я все еще изучаю регулярные выражения и много много комбинаций в алгоритмах.Все новые рекомендации приветствуются и будут добавлены ниже этой.

1 голос
/ 10 мая 2019

Согласно документам, Pattern.matches(regex,string) эквивалентно Pattern.compile(regex).matcher(string).matches(), что эквивалентно string.matches(regex). Это означает, что вы проверяете, соответствует ли вся строка регулярному выражению. Если вы хотите проверить, содержит ли строка маркер конца строки, вместо нее можно использовать Matcher.find:

Pattern pattern = Pattern.compile("([<])(-?\\d+)([>])");

String szBuffer = "";

if(mmInputStream.available() > 0) {
    ...

    szBuffer += convertedBytes;

    Log.d("SZ_BUFFER", szBuffer); 

    // <n>
    if(pattern.matcher(szBuffer).find()) {
        Log.d("SZ_BUFFER_ISMATCH", "MATCH!");
        szBuffer = "";
    }
    else
        Log.d("SZ_BUFFER_ISMATCH", "NO MATCH...");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...