字串有幾種變體:
"txt files `(*.txt)|*.txt|All files (*.*)|*.*`""Image Files`|*.jpg;*.jpeg;*.png;`""Excel Files `(*.xls, *.xlsx)|*.xls;*.xlsx|CSV Files (*.csv)|*.csv`"
子字串可以以任何(space, ',', '.', '|', ';') -無關緊要的字符結尾。
嘗試了以下選項:“ [^*].{3,4}(.?);", "[^*] .(.?);”。
我需要一個正則運算式來獲取string[] = {.jpg, .jpeg, ...},最好沒有重復的元素。
uj5u.com熱心網友回復:
你真的需要正則運算式嗎?
首先,如果你用 分割|,結果中的每個奇數條目都是一個擴展串列。然后,您可以再次拆分以獲取;擴展名,然后您可以將其展平為單個序列并修剪開始的每個元素*。最后,獲取不同的集合并將其放入陣列中。
這一切都可以通過Split和 Linq 來完成:
var extensions = filter.Split('|', StringSplitOptions.RemoveEmptyEntries)
.Where((x, i) => i % 2 != 0)
.SelectMany(x => x.Split(';', StringSplitOptions.RemoveEmptyEntries))
.Select(x => x.TrimStart('*'))
.Distinct()
.ToArray();
從拆分中洗掉空條目可確保如果您以分隔符結尾,它將被忽略。
在.NET Fiddle上查看它的實際效果。
uj5u.com熱心網友回復:
簡單拆分
我想我也會這樣做,Split并且應該可以這樣做:
str.Split('*',';','|')
.Where(s => s.StartsWith(".") && s[1..].All(Char.IsLetterOrDigit))
.Distinct();
注意:這對擴展的長度沒有任何堅持。如果需要,您可以為這些情況在 Where 中添加一些內容,例如:
&& s.Length is >3 and <6
.. 3 或 4 長度的擴展在 4 到 5 之間加上點,這就是“大于 3 且小于 6”的來源。請注意,它使用模式匹配,這是最近的 c# 添加。如果您的 c# 較舊,您將需要一些較舊的長度檢查樣式。
正則運算式
..但作為您學習正則運算式的機會,使用捕獲組更容易從字串中提取檔案擴展名:
var r = new Regex(@"\*(?<x>\.\w{3,4})\b");
var arr = r.Matches()
.Cast<Match>()
.Select(m => m.Groups["x"].Value)
.Distinct();
正則運算式本身會查找文字*,然后開始將字符捕獲到名為 x 的組中(?<x>。捕獲的字符是:文字點,后跟 3 到 4 個單詞字符(az,0-9)。我選擇了 3 和 4 之間,因為您的代碼選擇了它,但注意擴展可以更少或更多,因此您可以調整它。正則運算式的最后一位需要\b3 或 4 個字符后的字邊界,因為我們不希望部分匹配超過 4 個字符的擴展名。單詞邊界意味著擴展在 3 或 4 個字符后完成(下一個字符是非單詞字符)
要使用 LINQ 從中提取該資料,我們必須執行類似于Cast將結果集合條目添加到 Match 的操作;它們已經是 Matches 但是 MatchCollection 沒有實作IEnumerable<T>,因為它很舊,所以它不是 LINQ 兼容的,除非我們做一些像 Cast 這樣的事情來做到這一點。
從捕獲組中Select檢索字串值,這是.xxx擴展并Distinct洗掉重復項
你的正則運算式
至于為什么你的嘗試沒有奏效:
[^*]
.{3,4}
(.?)
;
這匹配
- char 是除星號以外的任何字符,
- 后跟 3 或 4 個任意字符,
- 后跟零個或一個任何字符,它被捕獲到一個未命名的組中,
- 后跟分號”。
在某些情況下它可能會被調整以作業,但它似乎沒有指定您正在尋找的字符模式
[^*]
.
(.?)
;
這匹配
- one or more of char that is any char except asterisk,
- followed by any char,
- followed by zero or one of any char that is captured into an unnamed group,
- followed by semicolon"
I suspect you're thinking that ^ is an escape that allows to match literal * - escape is \,
When ^ used as the first char inside [ ] it means "all chars except" so where I suspect you were trying to match a literal asterisk you actually ended up matching the exact opposite
Actually most chars lose their special meaning when placed inside a character class so [*] would be "match literal asterisk" just like \* is
uj5u.com熱心網友回復:
您的示例字串似乎包含括號之間的可選前導部分,后跟管道|,然后是擴展名。
如果要匹配資料的格式,可以使用同名的捕獲組,以及Group.Captures 屬性。
\b[fF]iles\b[^*()]*(?:\([^()]*\))?\|\*(?<ext>\.[\w*] )(?:[,;]\*(?<ext>\.[\w*] ))*
在部分情況下,模式匹配:
\b[fF]iles\b匹配檔案或檔案[^*()]*可選匹配任何字符,除了*()(?:\([^()]*\))?可選地匹配括號之間的部分\|\*匹配|*(?<ext>\.[\w*] )命名組ext, match.和 1 times a word char 或*(?:非捕獲組[,;]\*匹配,或;后跟*(?<ext>\.[\w*] )組分機的相同模式
)*關閉非捕獲組并可選地重復它以獲取所有擴展
請參閱C# regex 101 演示和C# 演示。
例如
string pattern = @"\b[fF]iles\b[^*()]*(?:\([^()]*\))?\|\*(?<ext>\.[\w*] )(?:[,;]\*(?<ext>\.[\w*] ))*";
string input = @"txt files `(*.txt)|*.txt|All files (*.*)|*.*`
Image Files`|*.jpg;*.jpeg;*.png;`
Excel Files `(*.xls, *.xlsx)|*.xls;*.xlsx|CSV Files (*.csv)|*.csv`";
var strings = Regex.Matches(input, pattern)
.SelectMany(m => m.Groups["ext"].Captures.Select(c => c.Value))
.ToArray()
.Distinct();
foreach (var s in strings)
{
Console.WriteLine(s);
}
輸出
.txt
.*
.jpg
.jpeg
.png
.xls
.xlsx
.csv
另一個與資料格式無關的較短模式,匹配一個點和 3 或 4 個單詞字符或星號并在左側斷言一個點:
(?<=\*)\.(?:\w{3,4}\b|\*)
查看另一個正則運算式演示。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/442610.html
上一篇:使用隨機字母移位解密訊息
