2017-10-07 72 views
0

我有一個看起來像這樣的文本字符串:我如果沒有指定名稱是應該添加名稱條目的功能正則表達式替換包含一個字符串,並且不包含另一個子

[customer id = "1" name="Bob" ...] 
[customer id="2" name="Adam" ...] 
[customer id="3" ...] 
[customer id = "4" name="Julia" ...] 

string AddNameIfDoesNotSpecified(string text, string id, string name) 
{ 
    return Regex.Replace(text, 
        $"id\\s*=\\s*\"{id}\"", 
        $"id=\"{id}\" name=\"{name}\"", 
        RegexOptions.IgnoreCase | RegexOptions.Compiled); 
} 

這個工作原理除了即使有指定的名稱它也會替換。如何更改正則表達式以檢查子字符串是否存在"name\\s*=",如果存在 - 不要替換?

,我需要實現的另一件事是UpdatName方法:

string UpdateNameIfSpecified(string text, string id, string oldName, string newName) 
{ 
    return Regex.Replace(text, 
        $"id\\s*=\\s*\"{id}\" name\\s*=\\s*\"{oldName}\"", 
        $"id=\"{id}\" name=\"{newName}\"", 
        RegexOptions.IgnoreCase | RegexOptions.Compiled); 
} 

它的工作原理,但如果我們有idname之間等其他屬性:

[customer id="5" gender="female" name="Marta" ...]

它不會工作,我如何使用正則表達式在C#中工作?我應該使用組嗎?

例子:

AddNameIfDoesNotSpecified("[customer id = \"6\" ...]", "6", "Alex") 
       // output: "[customer id=\"6\" name=\"Alex\" ...]" 

AddNameIfDoesNotSpecified("[customer id =\"7\" gender=\"male\" name=\"Greg\" ...]", "7", "Eric") 
       // output: "[customer id=\"7\" gender=\"male\" name=\"Greg\" ...]" 

UpdateNameIfSpecified("[customer id = \"8\" ...]", "8", "Sam", "Don") 
      // output: "[customer id=\"8\" ...]" 

UpdateNameIfSpecified("[customer id = \"9\" name=\"Lisa\" ...]", "9", "Lisa", "Carl") 
      // output: "[customer id=\"9\" name=\"Carl\" ...]" 

UpdateNameIfSpecified("[customer id=\"10\" gender=\"female\" name=\"Megan\" ...]", "10", "Megan", "Amy") 
      // output: "[customer id=\"10\" gender=\"female\" name=\"Amy\" ...]" 

UpdateNameIfSpecified("[customer id = \"11\" name=\"Tim\" ...]", "11", "Timothy", "Andrew") 
      // output: "[customer id=\"11\" name=\"Tim\" ...]" 
+3

_有些人遇到問題時會想:「我知道,我會用正則表達式。」現在他們有兩個問題_;) – Fabio

+0

你有一些數據(鍵值對)串行化爲一個字符串行。 1.反序列化它以鍵入您的語言理解。2.通過語言編譯器提供的好處以簡單的方式操作數據。 3.回到格式化的字符串行。很明顯,你應該有這種代表你的數據的類,因爲你的應用程序以某種方式使用它... – Fabio

回答

0
  1. 如何修改我正則表達式來檢查是否有 「名\ S * =」 字符串,如果它的存在 - 不做更換?

你可以簡單地檢查一個空的name屬性如下:

Regex.Replace(text, 
    $"id\\s*=\\s*\"{id}\"\\s+name\\s*=\\s*\"\"", 
    $"id=\"{id}\" name=\"{name}\"", 
    RegexOptions.IgnoreCase | RegexOptions.Compiled); 

但是,如果有如圖所示here之間的其他屬性,這是行不通的。

  • 如果我們有ID和名之間其他屬性..它是行不通的。我應該使用組嗎?
  • 是,這個想法是捕捉你的屬性之間的文本,然後再次使用它的組號(在我的模式$ 2)添加ID:

    Regex.Replace(text, 
    $"(id\\s *=\\s *\"{id}\")(.*?)(name\\s*=\\s*\"{oldName}\")", 
    $"id=\"{id}\"$2name=\"{newName}\"", 
        RegexOptions.IgnoreCase | RegexOptions.Compiled) 
    

    這同樣適用於第一圖案:

    $"id\\s*=\\s*\"{id}\"(.*?)name\\s*=\\s*\"\"", 
    $"id=\"{id}\"$1name=\"{name}\"", 
    

    雖然這個工程可能值得探索使用某種文檔對象模型/ XML更加靈活。

    0

    對於第一個,使用前向斷言

    $"id\\s*=\\s*\"{id}\"(?!.*?name\\s*=)", 
        $"id=\"{id}\" name=\"{name}\" ", 
    

    對於第二個,使用捕獲組

    $"id\\s*=\\s*\"{id}\"(.*?)name\\s*=\\s*\"{oldName}\"", 
        $"id=\"{id}\"$1name=\"{newName}\"", 
    

    檢查創建時這些字符串看起來像一個正則表達式。

    而且,要知道,\s將跨越換行符
    (使用[^\S\r\n]避免)

    .*?不會跨越換行符(如果你需要它使用一個點的所有修改)。

    +0

    它不工作。你的模式有錯誤。 – wp78de

    +0

    適用於我https://regex101.com/r/H8yoE9/2 – sln

    相關問題