2014-02-26 33 views
1

我有我的文本行像:Java的正則表達式開始有了和結尾爲條件代用品

=== Keno === 

我想這樣做if a line starts with = and ends with =我想提出一個新的行字符和下得分。我的意思是:

=== Keno === 
_ 

我想用正則表達式來使用Java。我怎樣才能做到這一點?

PS:輸入不是單行。我想檢查輸入的每一行是否符合我的需要。

+1

時候會人們開始使用正則表達式來處理它的好處了嗎? 'String#startsWith()'和'String#endsWith()'看起來不夠花哨?另外,替換並不是真正的正則表達式,它們是關於*匹配*的東西。 – Smutje

+0

輸入不是一行。我想檢查輸入字符串中的每一行。 – kamaci

+0

迭代是不可能的? – Smutje

回答

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這個,如果你正在工作但是,我認爲正則表達式是過度殺傷性的。


更新:

我做了正則表達式VS中午正則表達式的一些快速的測試,在我做的所有測試正則表達式的方法就出來了慢。這可能會改變,這取決於顯然的輸入數據,我所有的不同輸入。隨意測試自己,我使用的代碼列在下面(雖然有不同/更大的測試數據)。

我不會發布任何結果,因爲我沒有做過任何廣泛的測試,但沒有任何輸入,正則表達式比非正則表達式更快,我相信您可以進一步優化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

而不是\ n你可能會更好用System.getProperty(「line.separator」) – arajashe

+0

謝謝,更新了我的答案。 – rvalvik

1

如果你真的想要的正則表達式那麼這應該工作:

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

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

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

+1我會使用'System.getProperty(「line.separator」)'而不是'\ n' –

+0

是的,謝謝,它會比'\ n'更好。 – anubhava

0

你不需要正則表達式這一點。

判斷行開始,以=結束,如果真的更換線

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.. 
} 
相關問題