Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中,如何在不使用正则表达式的情况下按空字符分割字符串_Java_Regex - Fatal编程技术网

在Java中,如何在不使用正则表达式的情况下按空字符分割字符串

在Java中,如何在不使用正则表达式的情况下按空字符分割字符串,java,regex,Java,Regex,我有表格的代码 String[] splitValues = s.split("\\u0000"); 这就是所谓的alot,当我进行分析时,我看到每个调用都是一个要编译和运行的正则表达式模式,这会对性能产生重大影响 我可以简单地编译一次模式,但是运行split仍然需要占用大量的cpu 然后我查看了String、split的代码,如果只传递了一个字符或反斜杠字符,它会进行优化,但对我不起作用,因为我将null指定为\u0000,但我看不出还有什么其他方法可以做到 public String[]

我有表格的代码

 String[] splitValues = s.split("\\u0000");
这就是所谓的alot,当我进行分析时,我看到每个调用都是一个要编译和运行的正则表达式模式,这会对性能产生重大影响

我可以简单地编译一次模式,但是运行split仍然需要占用大量的cpu

然后我查看了String、split的代码,如果只传递了一个字符或反斜杠字符,它会进行优化,但对我不起作用,因为我将null指定为\u0000,但我看不出还有什么其他方法可以做到

public String[] split(String regex, int limit) {
        /* fastpath if the regex is a
         (1)one-char String and this character is not one of the
            RegEx's meta characters ".$|()[{^?*+\\", or
         (2)two-char String and the first char is the backslash and
            the second is not the ascii digit or ascii letter.
         */
        char ch = 0;
        if (((regex.length() == 1 &&
             ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||
             (regex.length() == 2 &&
              regex.charAt(0) == '\\' &&
              (((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 &&
              ((ch-'a')|('z'-ch)) < 0 &&
              ((ch-'A')|('Z'-ch)) < 0)) &&
            (ch < Character.MIN_HIGH_SURROGATE ||
             ch > Character.MAX_LOW_SURROGATE))
        {

如何在不使用正则表达式的情况下按空分隔符拆分?

简单的方法是预编译正则表达式:

static final Pattern NULL_SEPARATOR = Pattern.compile("\\u0000");
然后执行与上相同的操作:

或者,您可以将内容添加到列表中,而不是构建数组:

List<String> parts = new ArrayList<>();
for (int i = 0; i < input.length();) {
  int start = i;
  i = input.indexOf('\0', start);
  if (i < 0) i = input.length();

  parts.add(input.substring(start, i));

  if (i < input.length()) {
    ++i;
  }
}
当然,这会给你一个列表,而不是一个字符串[];这可能对你有用,也可能不有用。这样可以方便地为您增加集合,但您也可以使用字符串[]来实现这一点


根据[Prime],您可能需要考虑对列表进行预调整,例如,将查找0S的字符作为第一遍迭代。

< P>有一个开源java库MGNtutul,它有一个将字符串转换成Unicode序列的实用程序,反之亦然:

result = "Hello World";
result = StringUnicodeEncoderDecoder.encodeStringToUnicodeSequence(result);
System.out.println(result);
result = StringUnicodeEncoderDecoder.decodeUnicodeSequenceToString(result);
System.out.println(result);
此代码的输出为:

\u0048\u0065\u006c\u006c\u006f\u0020\u0057\u006f\u0072\u006c\u0064
Hello World
所以我建议您可以编写这样一个简单的代码

public static final String DELIMITER = StringUnicodeEncoderDecoder.decodeUnicodeSequenceToString("\\u0000");
...
String[] splitValues = s.split(DELIMITER);
这将允许您在不使用regex的情况下运行split方法,因为分隔符将null符号作为字符串保存。 该库可以在或处找到,它作为maven工件提供,并带有源代码和javadoc

下面是类的javadoc

String[] splitValues = s.split("\\u0000");

继续工作,但重要的是允许String.split使用其快速路径,因此拆分工作无需使用正则表达式


我发现稍微有点困惑的是,为什么我最初有一个“A”,因为这并不意味着把它当作文字反斜杠,因此如果你的数据中间有一个0,那么UMUN就不会被当作Unicode Char?< /P>。字符串可能不是数据的最佳容器。@FedericoklezCulloca数据来自ID3元数据,它使用\0在字符串中表示多个字符串,因此这是起点,不能更改。我明白了,但您可能应该将这些元数据读取为字节[],在\0上分隔,然后将部分放入字符串中。读取字符串中的二进制数据通常不会有好的结果。@FedericoklezCulloca它不是二进制数据,它的文本数据请只解决我有的具体问题好的,我可以使用列表的想法,这样迭代字符会更快吗?我已经做了预编译,这样基本上可以节省时间,但是仍然使用正则表达式是很重要的,你必须尝试一下。使用indexOf可能比手动迭代要快。只是想知道字符串[]splitValues=s.split\0;工作并允许使用字符串,拆分fastpath避免使用regex?是的,上面的测试和配置工作不需要使用rexex,所以这毕竟是一个非常简单的解决方案

String[] splitValues = s.split("\\u0000");
String[] splitValues = s.split("\0");