这是我的代码:
String str = "just_a_string";
System.out.println("]" + str + "[");
System.out.println("]" + str.replace("", "") + "[");
System.out.println("]" + str.substring(5) + "[");
System.out.println("]" + str.substring(5).replace("", "") + "[");
System.out.println("]" + str.substring(3, 8) + "[");
System.out.println("]" + str.substring(3, 8).replace("", "") + "[");
System.out.println("]" + "sdajndan".substring(5).replace("", "") + "[");
这是输出
05-09 19:09:20.570: I/System.out(23801): ]just_a_string[
05-09 19:09:20.570: I/System.out(23801): ]just_a_string[
05-09 19:09:20.570: I/System.out(23801): ]a_string[
05-09 19:09:20.570: I/System.out(23801): ]a_s[ **
05-09 19:09:20.570: I/System.out(23801): ]t_a_s[
05-09 19:09:20.570: I/System.out(23801): ]t_[ **
05-09 19:09:20.570: I/System.out(23801): ][ **
显然,标有**的行是意外的。
此问题发生在我的Android手机A(LG P920 Optimus 3D,Android 2.3.3)上。当我在Android手机B(LG E720
Optimus Chic,Android 2.2)上进行测试时,它停止了。我猜想它会陷入无限循环。
我已经用Java 1.5
和Java在这两款手机上进行了测试1.6
。两者分别导致相同的行为。
我还测试了在我同一个Eclipse与 Java的 项目,对1.5
,1.6
和1.7
。正如预期的那样,它们的所有输出都是正确的。
我想这可能是String.replace(“”, “”)
针对String的后备数组实现的特定于设备的问题。
您能帮我在您的设备中进行测试吗?
有人可以向我提供该String.replace(CharSequence, CharSequence)
方法的Android源代码吗?(例如docjar中的内容)
非常感谢!
我已经修改了一些代码,因此它也可以显示在Android设备上。(无论如何,这只是相同的代码)。
如上所述,我在手机A和手机B上都进行了测试。行为仍然相同。
package com.example.testprojectnew;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends Activity {
String output_text = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String str = "just_a_string";
process("1]" + str + "[");
process("2]" + str.replace("", "") + "[");
process("3]" + str.substring(5) + "[");
process("4]" + str.substring(5).replace("", "") + "[");
process("5]" + str.substring(3, 8) + "[");
process("6]" + str.substring(3, 8).replace("", "") + "[");
process("7]" + "sdajndan".substring(5).replace("", "") + "[");
output_text = output_text.concat("\n\nLines (1 & 2), (3 & 4), (5 & 6), should be the same.");
((TextView) findViewById(R.id.a_string)).setText(output_text);
}
private void process(String str) {
System.out.println(str);
output_text = output_text.concat(str).concat("\n");
}
}
感谢@izht提供源代码的链接。我已找到有关此问题的错误。
仅当String的后备数组具有与实际String不同(更长)的值时,才会发生这种情况。特别是String.offset
(私有变量)大于零时。
解决方法是:
public String replace(CharSequence target, CharSequence replacement) {
if (target == null) {
throw new NullPointerException("target == null");
}
if (replacement == null) {
throw new NullPointerException("replacement == null");
}
String targetString = target.toString();
int matchStart = indexOf(targetString, 0);
if (matchStart == -1) {
// If there's nothing to replace, return the original string untouched.
return this;
}
String replacementString = replacement.toString();
// The empty target matches at the start and end and between each character.
int targetLength = targetString.length();
if (targetLength == 0) {
int resultLength = (count + 2) * replacementString.length();
StringBuilder result = new StringBuilder(resultLength);
result.append(replacementString);
// for (int i = offset; i < count; ++i) { // original, bug
for (int i = offset; i < (count + offset); ++i) { // fix
result.append(value[i]);
result.append(replacementString);
}
return result.toString();
}
StringBuilder result = new StringBuilder(count);
int searchStart = 0;
do {
// Copy characters before the match...
result.append(value, offset + searchStart, matchStart - searchStart);
// Insert the replacement...
result.append(replacementString);
// And skip over the match...
searchStart = matchStart + targetLength;
} while ((matchStart = indexOf(targetString, searchStart)) != -1);
// Copy any trailing chars...
result.append(value, offset + searchStart, count - searchStart);
return result.toString();
}
我不确定为什么Android必须以replace()
这种方式更改(并错误地更改)。原始的Java实现没有此问题。
顺便说一下, 现在是什么? 我该怎么办?(除了replace()
格外小心使用,或丢弃我的Android手机:-/)
顺便说一句,我很确定我的LG E720 Optimus Chic(Android
2.2)使用的源代码与此不同。在目标字符串String.replace()
为
空的情况下, 它会继续停止(可疑无限循环)。最近我发现它抛出此错误消息:
05-10 16:41:13.155: E/AndroidRuntime(9384): FATAL EXCEPTION: main
05-10 16:41:13.155: E/AndroidRuntime(9384): java.lang.OutOfMemoryError
05-10 16:41:13.155: E/AndroidRuntime(9384): at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:97)
05-10 16:41:13.155: E/AndroidRuntime(9384): at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:157)
05-10 16:41:13.155: E/AndroidRuntime(9384): at java.lang.StringBuilder.append(StringBuilder.java:217)
05-10 16:41:13.155: E/AndroidRuntime(9384): at java.lang.String.replace(String.java:1497)
05-10 16:41:13.155: E/AndroidRuntime(9384): at com.example.testprojectnew.MainActivity.onCreate(MainActivity.java:22)
05-10 16:41:13.155: E/AndroidRuntime(9384): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
05-10 16:41:13.155: E/AndroidRuntime(9384): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
05-10 16:41:13.155: E/AndroidRuntime(9384): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
05-10 16:41:13.155: E/AndroidRuntime(9384): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
05-10 16:41:13.155: E/AndroidRuntime(9384): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
05-10 16:41:13.155: E/AndroidRuntime(9384): at android.os.Handler.dispatchMessage(Handler.java:99)
05-10 16:41:13.155: E/AndroidRuntime(9384): at android.os.Looper.loop(Looper.java:123)
05-10 16:41:13.155: E/AndroidRuntime(9384): at android.app.ActivityThread.main(ActivityThread.java:4627)
05-10 16:41:13.155: E/AndroidRuntime(9384): at java.lang.reflect.Method.invokeNative(Native Method)
05-10 16:41:13.155: E/AndroidRuntime(9384): at java.lang.reflect.Method.invoke(Method.java:521)
05-10 16:41:13.155: E/AndroidRuntime(9384): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:878)
05-10 16:41:13.155: E/AndroidRuntime(9384): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636)
05-10 16:41:13.155: E/AndroidRuntime(9384): at dalvik.system.NativeStart.main(Native Method)
仔细考虑一下,如果那个for循环的东西 是 bug。这应该是一个编译时问题。为什么在不同的手机(不同版本的Android)中,它的行为会有所不同?
获得了 Google
的更新,他们已经对其进行了修补,并将在以后的版本中进行更正。
同时,我根据他们的代码编写了一个修补方法:
(这是必要的,因为(1)我们仍然必须等待正确的发布,(2)我们需要照顾没有进行该固定更新的设备)
/** Patch for the String.replace(CharSequence target, CharSequence replacement),
* because the original is buggy when CharSequence target is empty, i.e. "".
* Patched by Google Android: https://android-review.googlesource.com/58393
*/
public static String replacePatched(final String string, final CharSequence target, final CharSequence replacement) {
if (target == null) {
throw new NullPointerException("target == null");
}
if (replacement == null) {
throw new NullPointerException("replacement == null");
}
final String targetString = target.toString();
int matchStart = string.indexOf(targetString, 0);
if (matchStart == -1) {
// If there's nothing to replace, return the original string untouched.
return new String(string);
}
final char[] value = string.toCharArray(); // required in patch
final int count = value.length; // required in patch
final String replacementString = replacement.toString();
// The empty target matches at the start and end and between each character.
if (targetString.length() == 0) {
// The result contains the original 'count' characters, a copy of the
// replacement string before every one of those characters, and a final
// copy of the replacement string at the end.
final StringBuilder result = new StringBuilder(count + (count + 1) * replacementString.length());
result.append(replacementString);
for (int i = 0; i < count; ++i) {
result.append(value[i]);
result.append(replacementString);
}
return new String(result); // StringBuilder.toString() does not give exact length
}
final StringBuilder result = new StringBuilder(count);
int searchStart = 0;
do {
// Copy characters before the match...
result.append(value, searchStart, matchStart - searchStart);
// Insert the replacement...
result.append(replacementString);
// And skip over the match...
searchStart = matchStart + targetString.length();
} while ((matchStart = string.indexOf(targetString, searchStart)) != -1);
// Copy any trailing chars...
result.append(value, searchStart, count - searchStart);
return new String(result); // StringBuilder.toString() does not give exact length
}
详细版本:
/** Patch for the String.replace(CharSequence target, CharSequence replacement),
* because the original is buggy when CharSequence target is empty, i.e. "".
* Patched by Google Android: https://android-review.googlesource.com/58393
*/
public static String replacePatched(final String string, final CharSequence target, final CharSequence replacement) {
if (target == null) {
throw new NullPointerException("target == null");
}
if (replacement == null) {
throw new NullPointerException("replacement == null");
}
// String targetString = target.toString(); // original
final String targetString = target.toString();
// int matchStart = indexOf(targetString, 0); // original
int matchStart = string.indexOf(targetString, 0);
if (matchStart == -1) {
// If there's nothing to replace, return the original string untouched.
// return this; // original
return new String(string);
}
final char[] value = string.toCharArray(); // required in patch
final int count = value.length; // required in patch
// String replacementString = replacement.toString(); // original
final String replacementString = replacement.toString();
// The empty target matches at the start and end and between each character.
// int targetLength = targetString.length(); // original
// if (targetLength == 0) { // original
if (targetString.length() == 0) {
// int resultLength = (count + 2) * replacementString.length(); // original
// // The result contains the original 'count' characters, a copy of the
// // replacement string before every one of those characters, and a final
// // copy of the replacement string at the end.
// int resultLength = count + (count + 1) * replacementString.length(); // patched by Google Android
// StringBuilder result = new StringBuilder(resultLength); // original
final StringBuilder result = new StringBuilder(count + (count + 1) * replacementString.length());
result.append(replacementString);
// for (int i = offset; i < count; ++i) { // original
// int end = offset + count; // patched by Google Android
// for (int i = offset; i != end; ++i) { // patched by Google Android
for (int i = 0; i < count; ++i) {
result.append(value[i]);
result.append(replacementString);
}
// return result.toString(); // original
return new String(result); // StringBuilder.toString() does not give exact length
}
// StringBuilder result = new StringBuilder(count); // original
final StringBuilder result = new StringBuilder(count);
int searchStart = 0;
do {
// Copy characters before the match...
// result.append(value, offset + searchStart, matchStart - searchStart); // original
result.append(value, searchStart, matchStart - searchStart);
// Insert the replacement...
result.append(replacementString);
// And skip over the match...
// searchStart = matchStart + targetLength; // original
searchStart = matchStart + targetString.length();
// } while ((matchStart = indexOf(targetString, searchStart)) != -1); // original
} while ((matchStart = string.indexOf(targetString, searchStart)) != -1);
// Copy any trailing chars...
// result.append(value, offset + searchStart, count - searchStart); // original
result.append(value, searchStart, count - searchStart);
// return result.toString(); // original
return new String(result); // StringBuilder.toString() does not give exact length
}
Ruby将字符串像数字一样处理.我们用单引号('...')或双引号("...")将它们括起来. ruby> "abc" "abc" ruby> 'abc' "abc" 单引号和双引号在某些情况下有不同的作用.一个由双引号括起来的字符串允许字符由一个前置的斜杠引出,而且可以用#{}内嵌表达式.而 单引号括起来的字符串并不会对字符串作任何解释;你看到的是什么便是什么.几个例子: ruby>
本文向大家介绍Java字符串replace(),replaceFirst()和replaceAll()方法,包括了Java字符串replace(),replaceFirst()和replaceAll()方法的使用技巧和注意事项,需要的朋友参考一下 该方法 String类的replace()方法接受两个String值- 一个表示要替换的String(子字符串)部分。 另一个代表需要替换指定子字符串的
修改字符串 到目前为止,我们简单地搜索了一个静态字符串。正则表达式通常也用不同的方式,通过下面的 RegexObject 方法,来修改字符串。 方法/属性 作用 split() 将字符串在 RE 匹配的地方分片并生成一个列表, sub() 找到 RE 匹配的所有子串,并将其用一个不同的字符串替换 subn() 与 sub() 相同,但返回新的字符串和替换次数
我已经做了一个有效的解决方案,但它很无聊,也很不优雅: 如何使用Regex实现这一点?
问题内容: 我只是尝试使用该方法。而且它不起作用。 HTML: JS: 结果:我得到“ r”,而我想得到“ t” 知道为什么它不起作用? 问题答案: (JavaScript函数,而不是jQuery)返回字符串,请尝试以下操作:
除了后面使用正则表达式之外,java.lang.String的和方法有什么区别?对于简单的替换,如将替换为,有什么区别吗?