3

我有一个字符串:

*abc*
**def**
***ghi***

我想删除换行符开头的所有星号。输出应该是:

abc*
def**
ghi***

我使用了一个正则表达式:^\\*+

但它会删除字符串中的所有星号!我不明白为什么。

我的代码:

String input="*abc*\n**def**\n***hij***";
Pattern p=Pattern.compile("(^(\\*+))", Pattern.MULTILINE);
Matcher m=p.matcher(input);

while(m.find())
{input=input.replace(m.group(1), "");
}
System.out.println(input);
4

2 回答 2

3

But it removes all the astericks in the string! I couldn't understand why.

It's happening because of the replace() you do inside the while loop. If your pattern is found in the string, the the group(1) will contain the \\*+ part without the ^. So, if you replace *, it will replace all the * in the string.

For the 2nd time, it matches ** at the beginning. And then you replace group(1) which is **, and will also replace ** at the end. Remember, String#replace() method replaces all the occurrences. Try changing the 2nd line of your string to - **def***, and you will see that it will leave a single * at the end.

Since you just have to replace you don't have to use that while loop and the find() method. Simply use Matcher#replaceAll() method. Your regex is completely fine and you don't need any capture group there:

Pattern.compile("^\\*+", Pattern.MULTILINE).matcher(input).replaceAll("");

This can also be done with the simple String#replaceAll(). For that you can use (?m) flag expression in regex, which is equivalent to Pattern.MULTILINE:

Multiline mode can also be enabled via the embedded flag expression (?m).

So, just do:

input = input.replaceAll("(?m)^\\*+", "");
于 2013-09-22T06:06:50.890 回答
1

Use the (?m) switch and only one line is needed:

input = input.replaceAll("(?m)^\\*+", "");

That switch turns on "Caret and dollar match after and before newlines for the remainder of the regular expression".


Here's some test code:

String input = "*abc*\n**def**\n***hij***";
input = input.replaceAll("(?m)^\\*+", "");
System.out.println(input);

Output:

abc*
def**
ghi***
于 2013-09-22T06:07:46.880 回答