2012-01-19 59 views
2

我處於嚴格的Java環境。Java正則表達式匹配src =「abc」或src ='abc'

所以這個問題並不像在這個tite中那麼簡單,我沒有試圖解決我所遇到的問題,它對於更好的知識更具理論性。

我感興趣的是使用雙引號或簡單引號與src進行匹配,但如果是雙引號,則它也必須用雙引號關閉,同樣適用於簡單引號。

我知道,我可以重複的正則表達式本身,即:

String str = "src=\"hello/\" ... src='hello/' ..." 

println str.replaceAll ("src=((\"[^\"]+\")|('[^']+'))", "src=$1") 

我想要做的是這樣的:

println s.replaceAll ("src=([\"'][^\"']+[\"'])", "src=$1") 

然而,如果用雙引號開始,那麼應該允許在內容中使用簡單的引號,並且它必須以雙引號結尾,而不是簡單的引號。

問題2:

是否有可能把它與已發現的相同類型的引號的replaceAll? 可以說,對於這場比賽,取而代之的是2,爲此,換成2。 如何在不每次生成新字符串的情況下完成此操作?

編輯艾倫更多,例如對於問題二:

println "one ... two".replaceAll("(one)", "1").replaceAll("(two)", "2"); 

更多沿着這些線路(不正確)

println "one ... two".replaceMyMatches("(one)[^\\w]+(two)", "\$1{1}, \$2{2}") // prints string : one{1}, two{2} 

我要的是字符串:1,2

回答第一個問題,並從黑熊貓和傑夫沃克改變了一下:

String str = "src=\"1.png\" ... src='2.jpeg' ... src=\"3.p'ng\" ... src='4.jpe\"g' ... src='' ... src=\"\" ..." ; 

String regex = "src=(['\"])(.+?)\\1"; // closes with the quote that is in group 1 

println str.replaceAll(regex, '''src=$1../new_path/$2$1''') 

吐出:

src="../new_path/1.png" ... src='../new_path/2.jpeg' ... src="../new_path/3.p'ng" ... src='../new_path/4.jpe"g' ... src='' ... src="" ... 

如果想更換空的爲好,只是切換+反對明星正則表達式(我不希望出現這種情況)

的通知原始報價也在。

回答問題二見黑熊貓

+0

我不明白第二個問題。有任何例子? –

+0

@AlanMoore查看編輯的問題 – momomo

回答

2

我對問題1的回答最初是不正確的。這是一個更新版本。

要回答的問題1..See如果這個表達式可以幫助你: 的模式是:

src=(['"])(.*?)\1 

下面的代碼解釋每一塊。

import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public class Regex { 

    public static void main(String[] args) 
    { 
     final String regex = "src=(['\"])" // the ' or the " is in group 1 
       + "(.*?)" // match any character in a non-greedy fashion 
       + "\\1"; // closes with the quote that is in group 1 
     Pattern p = Pattern.compile(regex); 

     Matcher m = p.matcher("src=\"hello/\" ... src='goodbye/' ... " 
       + "src='this has a \" in it'"); 

     while (m.find()) 
     { 
     System.out.println("\nfound!"); 
     System.out.println("The quote was a " + m.group(1)); 
     System.out.println("the text was = " + m.group(2)); 
     } 
    } 
} 

這使輸出:

found! 
The quote was a " 
the text was = hello/ 

found! 
The quote was a ' 
the text was = goodbye/ 

found! 
The quote was a ' 
the text was = this has a " in it 

至於第二個問題,你將不得不使用比多一點的代碼。你創建你自己的StringBuffer並在你繼續時追加。我用一個圖來保存的替代品:

public static void question2() 
    { 
     Pattern p = Pattern.compile("one|two"); 
     Map<String, String> replacements = new HashMap<String, String>(); 

     replacements.put("one", "1"); 
     replacements.put("two", "2"); 

     StringBuffer result = new StringBuffer(); 

     String text = "one ... two"; 

     Matcher m = p.matcher(text); 

     while (m.find()) 
     { 
     m.appendReplacement(result, replacements.get(m.group())); 
     } 

     m.appendTail(result); 

     System.out.println(result.toString()); 

    } 

此輸出:

1 ... 2 
+0

太棒了!我猜測問題2是牽強附會的? – momomo

+0

你有沒有運行這個?我在第1部分中正在編譯你的正則表達式。我將繼續嘗試查看我的問題在哪裏。 –

+0

是的,我在Netbeans 6.9上使用JDK 6 .1 –

2

問題1的正則表達式是:

src=(['"])hello\1(用於Java字符串雙反斜線)

它的第一次報價或雙引號,則匹配與第一個引號相同的字符,使用反向引用。

所以對於更一般的情況下,我想:

^src=(['"])(.*?)\1$

然後更換可能是這樣的:

String regex = "^src=(['\"])(.*?)\\1$"; 
String newthing = "src=$2"; 

這是你想要什麼?基本上去除引號,同時強制匹配?

由於一個精明的評論,我現在明白,你想報價逃脫彼此。像Perl這樣的語言可以做到這一點,但它們不是通過正則表達式分析的。這種類型的東西屬於需要實際解析的一類問題。 (不記得實際的術語)

而不是替換,你將不得不檢查組2和「斷言」組1不存在。注意到我在正則表達式中添加了開始和結束錨點。

因此,像:

Pattern p = Pattern.compile("^src=(['\"])(.*?)\\1$"); 
Matcher m = p.matcher("src=\"what's up?\""); 
if (m.matches()) { 
    if (m.group(2).contains(m.group(1))) { 
     // fail, doesn't match 
    } 
} 
// success, follows all of the rules 

我無法理解你正在尋找的第二個問題,即使有更新。我會編輯這個答案,如果我明白了。

+1

+1 Nice and neat! –

+0

雖然海報希望能夠在字符串中包含其他類型的引號。他希望能夠解析src ='這是'一些文本' –

+2

啊,我現在看到了。我敢肯定,這是不可能的一個正則表達式。再次更新我的答案.... –

1

你可以嘗試這樣的事情

String str = "src=\"hello/\" ... src='hello/' ..."; 

System.out.println(str.replaceAll("src=([\"'])(.*?)\\1", "src='$2'")); 

訣竅是使用重用第一個匹配的模式\ 1在非常相同的正則表達式

0

對於第一個問題,你可以使用這個正則表達式:

"([\"'])(?:(?!\\1).)*\\1" 

第二部分沒有純正則表達式解決方案 - 至少不是Java。有關Java方式,請參閱this answer。因此,舉例來說,如果你有這樣的一個表:

{ "one" => "1", "two" => "2" } 

...你replacement()方法是通過查找,然後在表格中,使用捕獲組中的內容生成替換字符串的動態部分作爲鑰匙。

相關問題