Java Regex从条件替换开始并结束

时间:2014-02-26 12:06:17

标签: java regex string

我的文字就像:

=== Keno ===

我想这样做if a line starts with = and ends with =我想要换一个新的字符和得分。我的意思是:

=== Keno ===
_

我想用Java使用正则表达式。我怎么能这样做?

PS:输入不是一行。我想检查输入的每一行是否符合我的需要。

3 个答案:

答案 0 :(得分:1)

您可以试试以下内容:

String s = "=== Kendo ===";
String repl = "$1" + System.getProperty("line.separator") + "_";
String newString = s.replaceAll("(?m)^(=.*=)$", repl); // $1\n_

这也适用于多行字符串,例如:

=== foo ===
one
two
=== bar ===
three
four

会变成:

=== foo ===
_
one
two
=== bar ===
_
three
four

在这种情况下,使用replaceAll / regex对此有一定意义,如果您正在处理单个字符串,我会说正则表达式过度。


更新

我对正则表达式与正午正则表达式进行了一些快速测试,在所有测试中,我采用了正则表达式方法。这可能会根据输入数据显而易见地改变,我拥有的所有不同输入。请随意为自己测试,下面列出了我使用的代码(虽然测试数据不同/更大)。

我没有发布任何结果,因为我还没有进行任何广泛的测试,但是由于没有输入,正则表达式比非正则表达式更快,我确信你可以优化replaceAllNoRegex方法。

修改 添加了第三个选项:replaceAllIndex这更快,请注意我没有对此进行广泛测试,因此可能存在错误,但使用indexOf甚至循环使用所有字符时,一个甚至比似乎是令牌化器。

public static void main(String[] args) {
    String s = "=== Etiam ===\neu\nmagna\nsit\namet\norci\nrutrum\nfeugiat\n\n=== Nunc ===\nurna\nlorem,\negestas\net\nvarius\nfermentum,\nconsectetur\nsed\nmauris\n";

    long start = System.currentTimeMillis();
    for (int i = 0; i < 100000; i++)
        replaceAllNoRegex(s);

    System.out.println("Tokens: " + (System.currentTimeMillis()-start));

    start = System.currentTimeMillis();
    for (int i = 0; i < 100000; i++)
        replaceAllIndex(s);

    System.out.println("Index: " + (System.currentTimeMillis()-start));

    start = System.currentTimeMillis();
    for (int i = 0; i < 100000; i++)
        s.replaceAll("(?m)^(=.*?=)$", "$1\n_");

    System.out.println("Regex: " + (System.currentTimeMillis()-start));
}

public static String replaceAllNoRegex(String s) {
    StringTokenizer st = new StringTokenizer(s,"\n");
    StringBuilder sb = new StringBuilder();
    String next;
    while (st.hasMoreElements()) {
        next = (String) st.nextElement();
        sb.append(next);
        if (next.startsWith("=") && next.endsWith("=")) {
            sb.append("\n_");
        }
        sb.append("\n");
    }
    return sb.toString();
}

public static String replaceAllIndex(String s) {
    int index = 0, indexEnd, indexStart = 0;
    StringBuilder sb = new StringBuilder();

    while (index == 0 || (index = s.indexOf("\n=", index)) != -1) {
        indexEnd = s.indexOf("\n",index+2);
        if (indexEnd != -1 && s.charAt(indexEnd-1) == '=') {
            sb.append(s.substring(indexStart,indexEnd));
            sb.append("\n_\n");
            indexStart = indexEnd + 1;
        }
        index = indexEnd+1;
    }
    sb.append(s.substring(indexStart));
    return sb.toString();
}

答案 1 :(得分:1)

如果你真的想要正则表达式,那么这应该有效:

str = "=== Keno ===";
String repl = str.replaceFirst("(?m)^(=.*?=)$", "$1\n_");

或使用System.getProperty("line.separator")

String repl = str.replaceFirst("(?m)^(=.*?=)$", "$1" + 
                                               System.getProperty("line.separator") + "_");

答案 2 :(得分:0)

你不需要正则表达式。

检查行是否以=开头和结尾,如果为true,则替换

StringBuilder sb = new StringBuilder();
for(String line : content.split("\n")){
    if(line.startsWith("=") && line.endsWith("=")){
        line = line.append("\n_");
    }
    sb.append(line);
}
content = sb.toString();

但是如果你坚持使用正则表达式,那么条件就像这样

if(line.matches("\=.*\=")){
    // then..
}