[英]Regex for catching word with special characters between letters
我是正則表達式的新手,我正在為評論功能(在 C# 中)編寫一個高級褻瀆過濾器。 只是為了節省時間,我知道所有的過濾器都可以被愚弄,不管它們有多好,你不必告訴我。 我只是想讓它比基本的單詞替換更先進一點。 我已將任務分成幾個單獨的方法,這就是其中之一。
我需要的是一段特定的正則表達式,它可以捕獲如下字符串:
s_h_i_t
s h i t
S<>H<>I<>T
s_/h_/i_/t
s***h***i***t
你明白了。 我想我正在尋找的是一個正則表達式,上面寫着“一個或多個不是字母數字的字符”。 這應該包括空格和您可以在標准(西方)鍵盤上鍵入的所有特殊字符。 如果可能的話,它還應該包括換行符,這樣它就會捕捉到類似的東西
s
h
i
t
應始終至少存在一個字符,以避免可能的誤報,例如
Finish it.
這當然意味着像
sh_it
不會被抓住,但正如我所說,沒關系,它不必是完美的。 我只需要正則表達式,我可以自己拆分單詞並插入正則表達式。 我在 C# 代碼中設置了 RegexOptions.IgnoreCase 選項,因此實際單詞中的字符大小寫不是問題。 此外,這個正則表達式不應該擔心“leetspeek”,即單詞的一些實際字母被其他字符替換:
sh1t
我有一種不同的方法來處理這個問題。 預先感謝您的幫助。
讓我們看看這個正則表達式是否適合你:
/\w(?:_|\W)+/
\bs[\W_]*h[\W_]*i[\W_]*t[\W_]*(?!\w)
匹配不是單詞字符或字符_
或空白字符的字母之間的字符(也是換行符)
\b
(字邊界)確保Finish it
不會匹配
(?!\w)
確保 sh ituuu 不會匹配,您可能需要刪除/修改它,因為s_hittt
也不會匹配。 \bs[\W_]*h[\W_]*i[\W_]*t+[\W_]*(?!\w)
將匹配最后一個字符重復的單詞
修改\bs[\W_]*h[\W_]*i[\W_]*t[\W_]*?(?!\w)
將使最后一個字符類的匹配不貪心,並且在sh it&&&
中只sh it
將匹配
\bs[\W\d_]*h[\W\d_]*i[\W\d_]*t+[\W\d_]*?(?!\w)
將匹配sh1i444t
(字符之間的數字)
編輯:
(?!\w) 是一個負前瞻。 它基本上檢查您的匹配是否后跟一個單詞字符(單詞字符是 [A-z09_])。 它的長度為 0,這意味着它不會包含在匹配中。 如果你想捕捉像“s h i*tface”這樣的詞,你必須刪除它。 ( http://www.regular-expressions.info/lookaround.html )
一個詞的邊界[/b] 匹配一個詞的開始或結束的地方,它的長度是0,這意味着它匹配字符之間
[\W] 是一個否定字符類,我認為它等於 [^a-zA-Z0-9_] 或 [^\w]
好吧,HamZa 的回答奏效了。 但是,我在研究解決方案時遇到了程序問題。 當我只替換單詞時,我總是知道單詞的長度。 所以我確切地知道要用多少個星號來代替它。 如果我匹配shit
,我知道我需要加上 4 個星號。 但是如果我匹配s[^a-z0-9]+h[^a-z0-9]+[^a-z0-9]+i[^a-z0-9]+t
,我可能會抓住s#h#i#t
否則我可能會catch s------h------i--------t
。 在這兩種情況下,匹配文本的長度都會與模式的長度大不相同。 如何獲得匹配字符串的實際長度?
您想匹配每個字母用相同的非單詞字符分隔的單詞。
您可以使用
\b\p{L}(?=([\W_]+))(?:\1\p{L})+\b
請參閱正則表達式演示。 (我添加了(?!\n)
以使正則表達式對每一行都起作用,就好像它是一個單獨的字符串一樣。)詳細信息:
\b
- 單詞邊界\p{L}
- 一個字母(?=([\W_]+))
- 一個正向前瞻,它匹配緊隨其后的任何非單詞或_
字符的位置(捕獲到第 1 組)(?:\1\p{L})+
- 捕獲到第 1 組的相同字符序列的一個或多個重復和一個字母\b
- 單詞邊界。要檢查字符串中是否存在這樣的模式,您可以使用
var HasSpamWords = Regex.IsMatch(text, @"\b\p{L}(?=([\W_]+))(?:\1\p{L})+\b");
要返回字符串中的所有匹配項,您可以使用
var results = Regex.Matches(text, @"\b\p{L}(?=([\W_]+))(?:\1\p{L})+\b")
.Cast<Match>()
.Select(x => x.Value)
.ToList();
請參閱C# 演示。
如果您獲得Match.Length
並使用.Select(x => x.Length)
,則獲取每個字符串的長度很容易。 如果您需要獲取刪除所有特殊字符的字符串長度,只需使用.Select(x => x.Value.Count(c => char.IsLetter(c)))
(請參閱此 C# 演示)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.