[英]Split string into array of character strings
我需要将一个字符串拆分为一个单字符字符串数组。
例如,拆分“cat”将得到数组“c”、“a”、“t”
"cat".split("(?!^)")
这将产生
数组 ["c", "a", "t"]
"cat".toCharArray()
但是如果你需要字符串
"cat".split("")
编辑:这将返回一个空的第一个值。
String str = "cat";
char[] cArray = str.toCharArray();
如果输入中需要超出基本多语言平面的字符(一些 CJK 字符、新的表情符号...),则不能使用诸如"a💫b".split("(?!^)")
之类的方法,因为它们会破坏这些字符(结果到array ["a", "?", "?", "b"]
)并且必须使用更安全的东西:
"a💫b".codePoints()
.mapToObj(cp -> new String(Character.toChars(cp)))
.toArray(size -> new String[size]);
如果字符串包含代理对, split("(?!^)")
无法正常工作。 您应该使用split("(?<=.)")
。
String[] splitted = "花ab🌹🌺🌷".split("(?<=.)");
System.out.println(Arrays.toString(splitted));
输出:
[花, a, b, 🌹, 🌺, 🌷]
总结其他答案......
这适用于所有 Java 版本:
"cat".split("(?!^)")
这仅适用于 Java 8 及更高版本:
"cat".split("")
将字符串转换为单字符字符串数组的一种有效方法是执行以下操作:
String[] res = new String[str.length()];
for (int i = 0; i < str.length(); i++) {
res[i] = Character.toString(str.charAt(i));
}
但是,这并没有考虑到String
中的char
实际上可以表示 Unicode 代码点的一半这一事实。 (如果代码点不在 BMP 中。)要解决这个问题,您需要遍历代码点……这更复杂。
这种方法将比使用String.split(/* clever regex*/)
更快,并且可能比使用 Java 8+ 流更快。 它可能比这更快:
String[] res = new String[str.length()];
int 0 = 0;
for (char ch: str.toCharArray[]) {
res[i++] = Character.toString(ch);
}
因为toCharArray
必须将字符复制到新数组中。
for(int i=0;i<str.length();i++)
{
System.out.println(str.charAt(i));
}
在我之前的回答中,我混淆了 JavaScript。这里是对 Java 的性能分析。
我同意需要关注 Java String 中的 Unicode Surrogate Pairs。 这打破了像String.length()
这样的方法的意义,甚至打破了Character
的功能意义,因为它最终是一个技术性的 object,它可能不代表人类语言中的一个字符。
我实现了 4 种方法,将字符串拆分为字符表示字符串列表( String
s 对应于字符s 的人类含义)。 这是比较的结果:
一行是一个String
,由 1000 个任意选择的表情符号和 1000 个 ASCII 字符组成(1000 次<emoji><ascii>
,人类意义上总共 2000 个“字符”)。
实施:
public static List<String> toCharacterStringListWithCodePoints(String str) {
if (str == null) {
return Collections.emptyList();
}
return str.codePoints()
.mapToObj(Character::toString)
.collect(Collectors.toList());
}
public static List<String> toCharacterStringListWithIfBlock(String str) {
if (str == null) {
return Collections.emptyList();
}
List<String> strings = new ArrayList<>();
char[] charArray = str.toCharArray();
int delta = 1;
for (int i = 0; i < charArray.length; i += delta) {
delta = 1;
if (i < charArray.length - 1 && Character.isSurrogatePair(charArray[i], charArray[i + 1])) {
delta = 2;
strings.add(String.valueOf(new char[]{ charArray[i], charArray[i + 1] }));
} else {
strings.add(Character.toString(charArray[i]));
}
}
return strings;
}
static final Pattern p = Pattern.compile("(?<=.)");
public static List<String> toCharacterStringListWithRegex(String str) {
if (str == null) {
return Collections.emptyList();
}
return Arrays.asList(p.split(str));
}
附件(原始数据):
codePoints;classic;regex;lines
45;44;84;256
14;20;98;512
29;42;91;1024
52;56;99;2048
87;121;174;4096
175;221;375;8192
345;411;839;16384
667;826;1285;32768
1277;1536;2440;65536
2426;2938;4238;131072
如果原始字符串包含补充 Unicode 字符,则split()
将不起作用,因为它将这些字符拆分为代理对。 为了正确处理这些特殊字符,这样的代码有效:
String[] chars = new String[stringToSplit.codePointCount(0, stringToSplit.length())];
for (int i = 0, j = 0; i < stringToSplit.length(); j++) {
int cp = stringToSplit.codePointAt(i);
char c[] = Character.toChars(cp);
chars[j] = new String(c);
i += Character.charCount(cp);
}
也许您可以使用 for 循环遍历字符串内容并使用charAt
方法逐个字符提取字符。
例如,结合ArrayList<String>
,您可以获得单个字符的数组。
我们可以简单地做到这一点
const string = 'hello';
console.log([...string]); // -> ['h','e','l','l','o']
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax说
展开语法 (...) 允许扩展诸如数组表达式或字符串之类的可迭代对象...
因此,字符串可以非常简单地扩展为字符数组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.