2009-09-09 33 views
1

想象一下這樣的字符串:是否有正則表達式用於查找/替換大塊文本中所有行的共同開始?

if(editorPart instanceof ITextEditor){ 
     ITextEditor editor = (ITextEditor)editorPart; 
     selection = (ITextSelection) editor.getSelectionProvider().getSelection(); 
    }else if(editorPart instanceof MultiPageEditorPart){ 
     //this would be the case for the XML editor 
     selection = (ITextSelection) editorPart.getEditorSite().getSelectionProvider().getSelection(); 
    } 

我所看到的,在視覺上,即「共同」,在這些線路的啓動是二製表符。是否有一個正則表達式可以替換 - 僅在每行的開頭(包括第一行和最後一行),這個常見的開始,這樣在正則表達式之後,我最終得到的是相同的字符串,只有基本上沒有縮進?

我不能簡單地搜索在這種情況下,「兩個選項卡」,因爲有可能是在一行開始在文本的其他地方,但沒有兩個標籤。

我已經實現了不同的方法,這個功能,但想那會是一個有趣的挑戰正則表達式,如果可能的話,在所有

+0

是否應該用正則表達式來啓動字符串?這只是你感興趣的空白空間嗎? – 2009-09-09 00:16:03

+1

+1:真棒問題。我開始試圖解釋爲什麼這是不可能的,並且意識到我不能。所以我把它作爲一個挑戰,最終構建了一個甜美的正則表達式面試問題。;) – ojrac 2009-09-09 14:31:39

回答

5

在正則表達式的^符號一行的開頭匹配。所以:

/^\t\t//g 

會刪除行首的兩個選項卡。

+2

由於每行只有一個開頭,'g'修飾符沒有任何要做的事情。不過,這是無害的。 – pavium 2009-09-09 00:13:33

1

一般(即,如果你想匹配任意前綴,不一定兩個選項卡),有可能會或可能不會是一個辦法。這取決於您正在使用的正則表達式引擎。我猜想,或許真的大致這個威力工作:

\B^(.+).*?$(?:^\1.*?$)+\E 

請注意,我可能搞砸了正則表達式的語法,只是把它作爲排序的正則表達式僞代碼(\B開始串,^是行首,$是行尾,\E是行尾)

但是,這真的不是我用正則表達式做的工作。一個簡單的逐字符解析器似乎更適合。

1

這是絕對可能的。正如大家指出的那樣,儘管如此,我從來不會在真正的項目中造成這種情況。

我的回答,如果你好奇,is here。我試圖用Perl寫它,但它不支持可變長度lookbehinds。

編輯:固定它!鏈接的代碼現在可用。如果您想要提示,只需發表評論 - 但如果您想自己解決問題,我不想放棄。

+0

我在Java中只使用了lookahead,並且和你一樣 - 我的解決方案未能縮進* last *行。 : -/ – 2009-09-09 01:35:19

+0

向前看,這是你可以做的最好的:每一行都會刪除與它前面的行相同的字符。最後一行沒有行與之比較。 – ojrac 2009-09-09 04:35:34

1

不在一個正則表達式。您需要進行兩次傳遞:matches()查找最長的通用前綴,然後replaceAll()將其刪除。這是我最好的解決辦法:

import java.util.regex.*; 

public class Test 
{ 
    public static void main(String[] args) throws Exception 
    { 
    String target = 
     "\t\tif(editorPart instanceof ITextEditor){\n" 
     + "\t\t\tITextEditor editor = (ITextEditor)editorPart;\n" 
     + "\t\t\tselection = (ITextSelection) fee.fie().fum();\n" 
     + "\t\t}else if(editorPart instanceof MultiPageEditorPart){\n" 
     + "\t\t\t//this would be the case for the XML editor\n" 
     + "\t\t\tselection = (ITextSelection) fee.fie().foe().fum();\n" 
     + "\t\t}"; 
    System.out.printf("%n%s%n", target); 

    Pattern p = Pattern.compile("^(\\s+).*+(?:\n\\1.*+)*+"); 
    Matcher m = p.matcher(target); 
    if (m.matches()) 
    { 
     String indent = m.group(1); 
     String result = target.replaceAll("(?m)^" + indent, ""); 
     System.out.printf("%n%s%n", result); 
    } 
    } 
} 

。當然,這是假設(如喬納森·萊弗勒在他對你的問題的評論暗示)目標字符串不是一個更大的字符串的一部分,而你只是刪除空白。沒有這些假設,任務變得更加複雜。

相關問題