【问题标题】:Regex in Java failed to matchJava中的正则表达式无法匹配
【发布时间】:2020-05-29 10:45:12
【问题描述】:

我正在编写一个 Android 应用程序,我需要在其中使用正则表达式检查通过蓝牙接收的数据。

每个接收到的行的数据表达式应该是A= 137, B= 137, C= 138, D= 136, E= 134, F= 138, G= 137。我想首先确保数据匹配“A= ddd,B= ddd.....G= ddd”,而 d,值可以是 0-1023。然后,提取 A 到 G 的值并将它们放入 A 到 G 的数组中。我试图匹配它,但它总是失败。我知道 Android Studio 中有一个检查正则表达式功能,我也使用在线网站进行检查。它们都匹配但在应用程序中失败。

有人可以帮忙吗?以下是从蓝牙套接字接收和匹配的数据。

 void beginListenForData()
    {
        Log.d(TAG,"begin for listening");
        final Handler handler = new Handler();
        final byte delimiter = 10; //This is the ASCII code for a newline character

        stopWorker = false;
        readBufferPosition = 0;
        readBuffer = new byte[1024];
        workerThread = new Thread(new Runnable()
        {
            public void run()
            {
                Log.d(TAG,"runnable thread");
                while(!Thread.currentThread().isInterrupted() && !stopWorker)
                {
                    try
                    {
                        int bytesAvailable = mmInputStream.available();
                        if(bytesAvailable > 0)
                        {
                           // Log.d(TAG,"incoming data is available");
                            byte[] packetBytes = new byte[bytesAvailable];
                            mmInputStream.read(packetBytes);
                            for(int i=0;i<bytesAvailable;i++)
                            {
                                byte b = packetBytes[i];
                                if(b == delimiter)
                                {
                                    byte[] encodedBytes = new byte[readBufferPosition];
                                    System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
                                    final String data = new String(encodedBytes, "US-ASCII");
                                    readBufferPosition = 0;

                                    Log.d(TAG, "data = " + data);
                                    handler.post(new Runnable()
                                    {
                                        public void run()
                                        {
                                            textView.setText(data);
                                        }
                                    });


                                    if (data.matches("A= \\d*, B= \\d*, C= \\d*, D= \\d*, E= \\d*, F= \\d*, G= \\d*")){
                                        Log.d(TAG, "data matches");
                                        Pattern dataA = Pattern.compile("(?<== )\\d*");
                                        Matcher matcherA = dataA.matcher(data);

                                        Log.d(TAG, matcherA.group());


                                    }else{
                                        handler.post(new Runnable()
                                        {
                                            public void run()
                                            {
                                                textView.setText("invalid data");
                                            }
                                        });
                                    }

                                }
                                else
                                {
                                    readBuffer[readBufferPosition++] = b;
                                }
                            }
                        }
                    }
                    catch (IOException ex)
                    {
                        stopWorker = true;
                    }
                }
            }
        });

        workerThread.start();
    }

编辑: 用于打印来自Log.d(TAG, "data = " + data);的数据:

2020-02-14 00:43:21.768 5130-5297/com.example.insoleapp D/Signal Fragment: data = A= 137, B= 138, C= 142, D= 138, E= 139, F= 138, G= 138
2020-02-14 00:43:21.841 5130-5297/com.example.insoleapp D/Signal Fragment: data = A= 137, B= 138, C= 141, D= 137, E= 136, F= 134, G= 138
2020-02-14 00:43:21.971 5130-5297/com.example.insoleapp D/Signal Fragment: data = A= 138, B= 139, C= 140, D= 139, E= 138, F= 138, G= 136
2020-02-14 00:43:22.080 5130-5297/com.example.insoleapp D/Signal Fragment: data = A= 138, B= 140, C= 138, D= 137, E= 133, F= 139, G= 139
2020-02-14 00:43:22.183 5130-5297/com.example.insoleapp D/Signal Fragment: data = A= 138, B= 137, C= 139, D= 139, E= 138, F= 138, G= 138
2020-02-14 00:43:22.287 5130-5297/com.example.insoleapp D/Signal Fragment: data = A= 139, B= 138, C= 139, D= 137, E= 138, F= 139, G= 141
2020-02-14 00:43:22.398 5130-5297/com.example.insoleapp D/Signal Fragment: data = A= 140, B= 137, C= 141, D= 138, E= 137, F= 137, G= 140

【问题讨论】:

  • 在此处发布失败代码时,请描述如何失败。尝试创建一个 MCVE 而不是发布整个应用程序。
  • 我也没有看到你打印出data字符串,你怎么知道输入是正确的?
  • 感谢 Maarten 的推荐。我曾考虑将正则表达式和我的匹配字符串放在这里,但正如我所说,我已经在不同的平台上对其进行了测试,看起来还可以(即表达式与字符串匹配)。如果问题来自于我将暂停我从蓝牙收集数据的方式,因此我把整个功能放在这里进行调查。
  • 再次感谢,我已将打印输出数据放入已编辑会话中的问题中
  • 也许你的数据,例如以00 字节结尾,该字节被解码为0000 字符。当您从本机转到 Java 时,这种情况经常发生。字符串中的任何控制字符都会让你走错路。尝试首先trim()您的字符串:“返回一个值为该字符串的字符串,删除所有前导和尾随空格,其中空格定义为代码点小于或等于'U + 0020'的任何字符(空格特点)。”如果可行,您当然可以考虑在正确的数据上生成字符串。

标签: java android regex


【解决方案1】:

您正在从二进制数据中检索字符串。这意味着它们可能包含不是可打印字符而是控制字符的字符。这些与您的表达式不匹配,因此表达式填充失败。

要关注的主要是00 字符串结尾字符,它通常用于C 环境和可能的汇编中。这些通常在 JNI 级别被错误地复制到 Java 字符串中,或​​者被不幸的开发人员自己复制到 Java 字符串中。 Java 字符串对象具有明确的大小,并且不依赖于丑陋的空终止符。

要删除最后的控制字符,您可以调用String#trim() 以便删除控制字符。来自 JavaDoc:

返回一个值为该字符串的字符串,去掉所有前导和尾随空格,其中空格定义为代码点小于或等于'U+0020'的任何字符(空格字符)。

像这些控制字符在0x0020下面。

但是,您当然最好先创建没有此类控制字符或字符串结尾的String

【讨论】:

  • 不要忘记跟进您的问题。如果这解决了您的问题,如 cmets 中所述,请接受。目前,您已回答的 6 个问题中有 3 个未完成此操作!
【解决方案2】:

我可能会在这里使用String#split 并遍历每个字母/数字对:

String input = "A= 137, B= 137, C= 138, D= 136, E= 134, F= 138, G= 137";
String[] parts = input.split(",\\s*");
for (String part : parts) {
    String label = part.split("\\s*=\\s*")[0];
    int num = Integer.parseInt(part.split("=\\s*")[1]);
    if (num < 0 || num > 1024) {
        throw new IllegalArgumentException("Out of range value for label: " + label);
    }
}

这里的方法是首先正则表达式拆分,\s* 上的对字符串,生成一个字符串数组,如"A= 137"。然后,我们迭代该对数组,并再次在 \s*=\s* 上进行正则表达式拆分以隔离数字。最后,我们检查数字的范围是否在 0 到 1024 之间,如果不是,则抛出异常。

【讨论】:

    猜你喜欢
    • 2022-08-17
    • 1970-01-01
    • 2011-03-30
    • 2011-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-02
    相关资源
    最近更新 更多