Java 字符转义
Java character escaping
在编程时,我发现 java 字符串有奇怪的行为。我正在尝试将字符串解析为带有参数的命令:
下面是调试过程中变量的截图。
这是我读取命令的代码:
public List<String> readCommand(Sender sender, String command) {
boolean isInQuote = false;
List<String> splits = new ArrayList();
String current = "";
char[] arr = command.toCharArray();
for (int i = 0; i < command.toCharArray().length; i++) {
char c = arr[i];
if (c == '"') {
isInQuote = !isInQuote;
if (!isInQuote) {
splits.add(current);
current = "";
}
}
if (isInQuote) {
current += c;
} else {
if (c == ' ' || i == arr.length - 1) {
if (i == arr.length - 1) {
current += c;
}
splits.add(current);
current = "";
} else {
current += c;
}
}
}
return splits;
}
正如测试中预期的那样;该字符串应解析为:
- "this"
- "is a test"
- "now"
而是解析为:
- "this"
- "\"is a test"
- "\""
- "now"
为什么转义引号不起作用,我做错了什么?
P.S.: 我会尝试研究这个主题,但我不知道如何称呼它。正在用引号解析参数...?
更新:在你的帮助下,我发现了另一个我修复的错误。该代码现在可以正常工作。现在剩下的就是重新制作它:)。 \" 不工作真的让我很困惑。http://pastebin.com/AdBUqJvH
这是您任务的解决方案。
public static void main(String[] args) {
List<String> splits = readCommand("this \"is a\" test\" now");
for(String str : splits) {
System.out.println("_"+str+"_");
}
}
public static List<String> readCommand(String command) {
List<String> list = Arrays.asList(command.split("\""));
List<String> list2 = new ArrayList<>();
for(String str : list) {
str = checkFirst(str);
str = checkLast(str);
list2.add(str);
}
return list2;
}
private static String checkFirst(String str) {
if (str.charAt(0) == ' ') {
str = checkFirst(str.substring(1));
}
return str;
}
private static String checkLast(String str) {
if (str.charAt(str.length() - 1) == ' ') {
str = checkLast(str.substring(0, str.length() - 1));
}
return str;
}
你的代码对我来说工作得很好。除了输出是
这个"is a test"“现在
而不是
这个 "is a test" 现在
我为此做了一个小改动
你说你不知道输入并不总是包含'"',但是你用'"'硬编码它,所以[Igor Sadovnikov]的答案可能更好?
public static void main(String[] args) {
String s = "this \"is a test\" now";
List<String> commands = readCommand(null, s);
for (String command : commands) {
System.out.print(command + " ");
}
}
private static List<String> readCommand(Object sender, String command) {
boolean isInQuote = false;
List<String> splits = new ArrayList<String>();
String current = "";
char[] arr = command.toCharArray();
for (int i = 0; i < command.toCharArray().length; i++) {
char c = arr[i];
if (c == '"') {
isInQuote = !isInQuote;
if (!isInQuote) {
//CHANGE HERE ... added + c
splits.add(current + c);
current = "";
}
}
if (isInQuote) {
current += c;
} else {
if (c == ' ' || i == arr.length - 1) {
if (i == arr.length - 1) {
current += c;
}
splits.add(current);
current = "";
}
// --- CHANGE HERE
else if (c != '"') {
current += c;
}
}
}
return splits;
}
首先让我们简化您当前的尝试:
public static void main(String[] args) throws Exception {
String data = "this \"is a test\" now \"hello\" goodbye";
List<String> splits = new ArrayList();
String current = "";
boolean inQuote = false;
for (int i = 0; i < data.length(); i++) {
if (data.charAt(i) == ' ' && !inQuote) {
// Add your current split word and move on to the next character
splits.add(current);
current = "";
continue;
} else if (data.charAt(i) == '\"') {
// Flip the flag whenever you run across a quotation mark
inQuote = !inQuote;
}
// Add current character to string, spaces never get added
current += data.charAt(i);
}
// Add remaining split data from hitting the end of data
if (!current.isEmpty()) {
splits.add(current);
}
// Display results
for (String split : splits) {
System.out.println(split);
}
}
结果:
this
"is a test"
now
"hello"
goodbye
正则表达式
然后您可以使用 Regex
缩短您的代码,如下所示(结果相同):
public static void main(String[] args) throws Exception {
String data = "this \"is a test\" now \"hello\" goodbye";
Matcher matcher = Pattern.compile("[^\s\"']+|\"[^\"]*\"|'[^']*'").matcher(data);
while (matcher.find()) {
System.out.println(matcher.group());
}
}
在编程时,我发现 java 字符串有奇怪的行为。我正在尝试将字符串解析为带有参数的命令:
下面是调试过程中变量的截图。
这是我读取命令的代码:
public List<String> readCommand(Sender sender, String command) {
boolean isInQuote = false;
List<String> splits = new ArrayList();
String current = "";
char[] arr = command.toCharArray();
for (int i = 0; i < command.toCharArray().length; i++) {
char c = arr[i];
if (c == '"') {
isInQuote = !isInQuote;
if (!isInQuote) {
splits.add(current);
current = "";
}
}
if (isInQuote) {
current += c;
} else {
if (c == ' ' || i == arr.length - 1) {
if (i == arr.length - 1) {
current += c;
}
splits.add(current);
current = "";
} else {
current += c;
}
}
}
return splits;
}
正如测试中预期的那样;该字符串应解析为:
- "this"
- "is a test"
- "now"
而是解析为:
- "this"
- "\"is a test"
- "\""
- "now"
为什么转义引号不起作用,我做错了什么?
P.S.: 我会尝试研究这个主题,但我不知道如何称呼它。正在用引号解析参数...?
更新:在你的帮助下,我发现了另一个我修复的错误。该代码现在可以正常工作。现在剩下的就是重新制作它:)。 \" 不工作真的让我很困惑。http://pastebin.com/AdBUqJvH
这是您任务的解决方案。
public static void main(String[] args) {
List<String> splits = readCommand("this \"is a\" test\" now");
for(String str : splits) {
System.out.println("_"+str+"_");
}
}
public static List<String> readCommand(String command) {
List<String> list = Arrays.asList(command.split("\""));
List<String> list2 = new ArrayList<>();
for(String str : list) {
str = checkFirst(str);
str = checkLast(str);
list2.add(str);
}
return list2;
}
private static String checkFirst(String str) {
if (str.charAt(0) == ' ') {
str = checkFirst(str.substring(1));
}
return str;
}
private static String checkLast(String str) {
if (str.charAt(str.length() - 1) == ' ') {
str = checkLast(str.substring(0, str.length() - 1));
}
return str;
}
你的代码对我来说工作得很好。除了输出是
这个"is a test"“现在
而不是
这个 "is a test" 现在
我为此做了一个小改动
你说你不知道输入并不总是包含'"',但是你用'"'硬编码它,所以[Igor Sadovnikov]的答案可能更好?
public static void main(String[] args) {
String s = "this \"is a test\" now";
List<String> commands = readCommand(null, s);
for (String command : commands) {
System.out.print(command + " ");
}
}
private static List<String> readCommand(Object sender, String command) {
boolean isInQuote = false;
List<String> splits = new ArrayList<String>();
String current = "";
char[] arr = command.toCharArray();
for (int i = 0; i < command.toCharArray().length; i++) {
char c = arr[i];
if (c == '"') {
isInQuote = !isInQuote;
if (!isInQuote) {
//CHANGE HERE ... added + c
splits.add(current + c);
current = "";
}
}
if (isInQuote) {
current += c;
} else {
if (c == ' ' || i == arr.length - 1) {
if (i == arr.length - 1) {
current += c;
}
splits.add(current);
current = "";
}
// --- CHANGE HERE
else if (c != '"') {
current += c;
}
}
}
return splits;
}
首先让我们简化您当前的尝试:
public static void main(String[] args) throws Exception {
String data = "this \"is a test\" now \"hello\" goodbye";
List<String> splits = new ArrayList();
String current = "";
boolean inQuote = false;
for (int i = 0; i < data.length(); i++) {
if (data.charAt(i) == ' ' && !inQuote) {
// Add your current split word and move on to the next character
splits.add(current);
current = "";
continue;
} else if (data.charAt(i) == '\"') {
// Flip the flag whenever you run across a quotation mark
inQuote = !inQuote;
}
// Add current character to string, spaces never get added
current += data.charAt(i);
}
// Add remaining split data from hitting the end of data
if (!current.isEmpty()) {
splits.add(current);
}
// Display results
for (String split : splits) {
System.out.println(split);
}
}
结果:
this
"is a test"
now
"hello"
goodbye
正则表达式
然后您可以使用 Regex
缩短您的代码,如下所示(结果相同):
public static void main(String[] args) throws Exception {
String data = "this \"is a test\" now \"hello\" goodbye";
Matcher matcher = Pattern.compile("[^\s\"']+|\"[^\"]*\"|'[^']*'").matcher(data);
while (matcher.find()) {
System.out.println(matcher.group());
}
}