【问题标题】:Removing words with special characters in them删除带有特殊字符的单词
【发布时间】:2012-05-30 23:43:09
【问题描述】:

我有一个由许多不同单词组成的长字符串。

我想遍历所有这些,如果单词包含特殊字符或数字('-' 除外),或者以大写字母开头,我想删除它(整个单词不只是那个字符) .出于所有意图和目的,“外来”字母都可以算作特殊字符。

显而易见的解决方案是循环遍历每个单词(拆分后),然后循环遍历每个字符 - 但我希望有更快的方法吗?也许使用正则表达式,但我几乎没有使用它的经验。

谢谢

添加:

(例如我想要的:)

输入:“this Is an Example of 5 words in an input like-so from example.com”

输出:{this,an,of,words,in,an,input,like-so,from}

(到目前为止我已经尝试过)

List<string> response = new List<string>();

string[] splitString = text.Split(' ');

foreach (string s in splitString)
{
    bool add = true;
    foreach (char c in s.ToCharArray())
    {
         if (!(c.Equals('-') || (Char.IsLetter(c) && Char.IsLower(c))))
         {
             add = false;
             break;
         }
         if (add)
         {
             response.Add(s);
         }
    }
}

编辑 2:

对我来说,单词应该是由空格分隔的多个字符 (a..z)。 ,/./!/... 最后不应计入“特殊字符”条件(实际上主要是为了删除 url 等)

所以: “我看到一条狗。它是黑色的!” 应该导致 {saw,a,dog,was,black}

【问题讨论】:

  • 真的有必要吗?我认为我的问题完全可以理解。
  • 我们并不是要你把你的整个项目放在这里。您说“我有一个长字符串..” 将字符串的某些部分放在您希望进行检查的地方。然后告诉我们这个foo 单词应该检查bar 条件,结果输出应该是FooBar
  • @NikhilAgrawal 大多数程序员都能够将功能请求(“文学”)翻译成代码 - 阅读没有什么问题吗?也许 Aabela 在编写任何代码之前 正在考虑一个解决方案,这非常有意义。
  • @Aabela,请定义“单词”。 foo. 是单词还是单词后跟句号? 123、. 或 !#%&amp; 是一个词吗(要删除)?
  • 嗯,我希望它是“一个单词后跟一个句点”,但我没有考虑过这个问题 - 我只是用空格分隔它们 - 但我真的应该修复 .和 , 在结尾处。

标签: c# regex string


【解决方案1】:

那么您想查找所有仅包含字符a-z 或- 的“单词”,用于以空格分隔的单词?

这样的正则表达式会找到这样的词:

(?<!\S)[a-z-]+(?!\S)

为了还允许以单个标点符号结尾的单词,您可以使用:

(?<!\S)[a-z-]+(?=[,.!?:;]?(?!\S))

示例(ideone):

var re = @"(?<!\S)[a-z-]+(?=[,.!?:;]?(?!\S))";
var str = "this, Is an! Example of 5 words in an input like-so from example.com foo: bar?";

var m = Regex.Matches(str, re);

Console.WriteLine("Matched: ");
foreach (Match i in m)
    Console.Write(i + " ");

注意字符串中的标点符号。

输出:

Matched: 
this an of words in an input like-so from foo bar 

【讨论】:

  • 我试过这个,它似乎工作得很好。但是,它会过滤掉以标点符号结尾的单词。是否可以修改为不检查最后一个字符?
  • @Aabela,是的,你可以。更新并添加了一个示例。
  • PS: (?!\S) 只是(?=\s|$) 的一种更短的写法。
【解决方案2】:

这个怎么样?

(?

编辑:意思是(?&lt;=^|\s+)(?&lt;word&gt;[a-z\-]+)(?=(?:\.|,|!|\.\.\.)?(?:$|\s+))

规则:

  1. 单词前只能有行首或一定数量的空白字符
  2. 单词后面只能跟行尾或一定数量的空白字符(Edit 支持以句点、逗号、感叹号和省略号结尾的单词)
  3. Word 只能包含小写(拉丁)字母和破折号

包含每个单词的命名组是“word”

【讨论】:

  • 使用这个和解释我能够扩展它以允许单词后面也可以跟标点符号。谢谢。
  • 没问题。我刚刚意识到标点符号的问题并想出了(?&lt;=^|\s+)(?[a-z-]+)(?=$|\s+|\.|,|!|\.\.\.)。那是你扩展它的样子吗?
  • @MarkM:该模式无法编译。你不是错过了什么吗?我的意思是你提到的(?&lt;=^|\s+)(?[a-z-]+)(?=$|\s+)或(?&lt;=^|\s+)(?[a-z-]+)(?=$|\s+|\.|,|!|\.\.\.)中的named group在哪里?
  • 啊,是的,你是对的 - 复制错误。我的意思是(?&lt;=^|\s+)(?&lt;word&gt;[a-z\-]+)(?=$|\s+|\.|,|!|\.\.\.)。感谢您指出这一点。
  • 正则表达式 regex2 = 新正则表达式 ("(?
【解决方案3】:

看看微软的How to: Search Strings Using Regular Expressions (C# Programming Guide) - 它是关于 C# 中的正则表达式的。

【讨论】:

  • 我看了看,但我得到的印象是我仍然需要一次循环一个单词。这是我试图避免的。
【解决方案4】:
List<string> strings = new List<string>() {"asdf", "sdf-sd", "sdfsdf"};

for (int i = strings.Count-1; i > 0; i--)
{
   if (strings[i].Contains("-"))
   {
       strings.Remove(strings[i]);
   }
}

【讨论】:

    【解决方案5】:

    这可能是一个起点。现在它只检查“。”作为一个特殊的字符。这输出:“this an of words in an like-so from”

            string pattern = @"[A-Z]\w+|\w*[0-9]+\w*|\w*[\.]+\w*";
            string line = "this Is an Example of 5 words in an in3put like-so from example.com";
    
            System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex(pattern);
            line = r.Replace(line,"");
    

    【讨论】:

      【解决方案6】:

      您可以通过两种方式做到这一点,白名单方式和黑名单方式。使用白名单,您可以定义您认为可以接受的字符集,而使用黑名单则相反。

      让我们假设白名单方式并且您只接受字符a-z、A-Z 和- 字符。此外,您还有规则,单词的第一个字符不能是大写字符。

      有了这个,你可以做这样的事情:

      string target = "This is a white-list example: (Foo, bar1)";
      
      var matches = Regex.Matches(target, @"(?:\b)(?<Word>[a-z]{1}[a-zA-Z\-]*)(?:\b)");
      
      string[] words = matches.Cast<Match>().Select(m => m.Value).ToArray();
      
      Console.WriteLine(string.Join(", ", words));
      

      输出:

      // is, a, white-list, example
      

      【讨论】:

      • 不能按预期工作,例如 example.com(example 和 com 将匹配)或 123-fail(fail 将匹配)。
      • 是的,这个解决方案使用单词边界而不是空格。我在阅读更新之前发布了这个,因为其他答案解决了更新的问题,所以我没有费心更新。
      【解决方案7】:

      您可以使用前瞻和后瞻来执行此操作。这是一个与您的示例匹配的正则表达式:

      (?<=\s|^)[a-z-]+(?=\s|$)
      

      解释是:匹配一个或多个字母字符(仅小写,加上连字符),只要字符前面是空格(或字符串的开头),只要后面是空格或字符串的结尾。

      您现在需要做的就是将其插入System.Text.RegularExpressions.Regex.Matches(input, regexString) 以获取您的单词列表。

      参考:http://www.mikesdotnetting.com/Article/46/CSharp-Regular-Expressions-Cheat-Sheet

      【讨论】:

        猜你喜欢
        • 2018-11-29
        • 2020-02-29
        • 1970-01-01
        • 1970-01-01
        • 2014-05-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多