2009-07-21 30 views
4

例如,我有一個字符串:如何爲此場景編寫正則表達式?

/div1/div2[/div3[/div4]]/div5/div6[/div7] 

現在我想通過「/」的內容劃分,而忽略「[ ]」的內容。

結果應該是:

  1. div1
  2. div2[/div3[/div4]]
  3. div5
  4. div6[/div7]

我怎樣才能使用正則表達式的結果呢?我的編程語言是JavaScript。

+1

正則表達式在很大程度上是語言不可知的 - 但是,在少數情況下,請指定您正在使用的語言。 – 2009-07-21 07:06:27

+0

我希望能用javascript來解決這個問題。 – Mike108 2009-07-23 02:00:28

+0

我會堅持這個遞歸函數。每次看到一個[調用自己並返回它看到] – 2010-01-12 11:30:21

回答

2

這工作...

using System; 
using System.Text.RegularExpressions; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     string testCase = "/div1/div2[/div3[/div4]]/div5/div6[/div7]"; 
     //string pattern = "(?<Match>/div\\d(?:\\[(?>\\[(?<null>)|\\](?<-null>)|.?)*(?(null)(?!))\\])?)"; 
     string pattern = "(?<Match>div\\d(?:\\[(?>\\[(?<null>)|\\](?<-null>)|.?)*(?(null)(?!))\\])?)"; 

     Regex rx = new Regex(pattern); 

     MatchCollection matches = rx.Matches(testCase); 

     foreach (Match match in matches) 
      Console.WriteLine(match.Value); 

     Console.ReadLine(); 

    } 
} 

禮貌...... http://retkomma.wordpress.com/2007/10/30/nested-regular-expressions-explained/

3

你不能用正則表達式來做這件事,因爲它是遞歸的。 (這回答你的問題,現在看看我是否可以優雅地解決問題...)

編輯:aem提示我! :D

只要每個[後面跟着/。它驗證該字符串的格式是否正確。

string temp = text.Replace("[/", "["); 
string[] elements = temp.Split('/').Select(element => element.Replace("[", "[/")).ToArray(); 
+1

您可以做嵌套匹配,請參閱我的答案。 – MyItchyChin 2009-07-21 04:44:32

+0

事實上,你*可以*並不一定意味着你*應該* – 2009-07-21 07:07:03

2

你可以先轉換兩個字符序列[/成另一種字符或序列,你知道會不會出現在輸入,然後拆分開/邊界的字符串,然後翻譯序列重新翻譯回到[/結果字符串中。這甚至不需要正則表達式。 :)

例如,如果您知道[在您的輸入序列中不會自行顯示,您可以用[在第一步中替換[/]。

0

實驗例如,使用PHP和拆分的方法,但只對樣品進行測試的字符串。

$str = "/div1/div2[/div3[/div4]]/div5/div6[/div7]/div8"; 
// split on "/" 
$s = explode("/",$str); 
foreach ($s as $k=>$v){ 
    // if no [ or ] in the item 
    if(strpos($v,"[")===FALSE && strpos($v,"]") ===FALSE){ 
     print "\n"; 
     print $v."\n"; 
    }else{ 
     print $v . "/"; 
    } 
} 

輸出:

div1 
div2[/div3[/div4]]/ 
div5 
div6[/div7]/ 
div8 

注:有 「/」 結尾所以只是有點微調會得到想要的結果的。

0

s/\/(div\d{0,}(?:\[.*?\])?)/$1\n/

1

您的發帖歷史記錄來看,我想你是在談論C#(。 NET)正則表達式。在這種情況下,這應該工作:

Regex.Split(target, @"(?<!\[)/"); 

這是假定每個非分隔符/立即被左方括號前面,在你的樣本數據。

您應該始終指定您正在使用哪種正則表達式。例如,這種技術需要一種支持向後看的風格。在我的頭上,包括Perl,PHP,Python和Java,但不包括JavaScript。

編輯:這是一個Java示範:

public class Test 
{ 
    public static void main(String[] args) 
    { 
    String str = "/div1/div2[/div3[/div4]]/div5/div6[/div7]"; 

    String[] parts = str.split("(?<!\\[)/"); 
    for (String s : parts) 
    { 
     System.out.println(s); 
    } 
    } 
} 

輸出:

div1 
div2[/div3[/div4]] 
div5 
div6[/div7] 

當然,我靠這裏的一些簡化的假設。我相信你會讓我知道我的假設是否有錯,邁克。 :)

編輯:仍然等待從邁克關於假設的裁決,但克里斯盧茨在他的評論280Z28帶來了一個好點。在示例字符串的根級別,有兩個地方可以看到兩個連續的/divN令牌,但在其他每個級別,令牌總是通過方括號彼此隔離。我的解決方案,就像280Z28一樣,假定這總是正確的,但如果數據看起來像這樣呢?

/div1/div2[/div3/div8[/div4]/div9]/div5/div6[/div7] 

現在我們已經有了兩個地方非分隔符斜線由左方括號前面,但其基本思想是。從根級的任何一點開始,如果向前掃描查找方括號,則第一個找到的將始終是左括號(或開頭)。如果向後掃描,則始終會首先找到正確(或關閉)的括號。如果這兩種情況都不正確,那麼您不在根級別。翻譯,要lookarounds,你會得到這樣的:

/(?![^\[\]]*\])(?<!\[[^\[\]]*) 

我知道它變得非常粗糙,但我將在接管godawful遞歸東西每週的任何一天。 ;)另一個好處是你不必知道任何有關令牌的地方,除非它們以斜線開頭,並且不包含任何方括號。順便說一句,這個正則表達式包含一個可以匹配任意數量字符的lookbehind;支持的正則表達式的列表確實很短,但.NET可以做到這一點。