簡體   English   中英

用於捕獲字母之間具有特殊字符的單詞的正則表達式

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM