删除带有特殊字符的单词
Posted
技术标签:
【中文标题】删除带有特殊字符的单词【英文标题】: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
、.
或 !#%&
是一个词吗(要删除)?
嗯,我希望它是“一个单词后跟一个句点”,但我没有考虑过这个问题 - 我只是用空格分隔它们 - 但我真的应该修复 .和 , 在结尾处。
【参考方案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】:
这个怎么样?
(?
编辑:意思是(?<=^|\s+)(?<word>[a-z\-]+)(?=(?:\.|,|!|\.\.\.)?(?:$|\s+))
规则:
-
单词前只能有行首或一定数量的空白字符
单词后面只能跟行尾或一定数量的空白字符(Edit 支持以句点、逗号、感叹号和省略号结尾的单词)
Word 只能包含小写(拉丁)字母和破折号
包含每个单词的命名组是“word”
【讨论】:
使用这个和解释我能够扩展它以允许单词后面也可以跟标点符号。谢谢。 没问题。我刚刚意识到标点符号的问题并想出了(?<=^|\s+)(?[a-z-]+)(?=$|\s+|\.|,|!|\.\.\.)
。那是你扩展它的样子吗?
@MarkM:该模式无法编译。你不是错过了什么吗?我的意思是你提到的(?<=^|\s+)(?[a-z-]+)(?=$|\s+)
或(?<=^|\s+)(?[a-z-]+)(?=$|\s+|\.|,|!|\.\.\.)
中的named group
在哪里?
啊,是的,你是对的 - 复制错误。我的意思是(?<=^|\s+)(?<word>[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
【讨论】:
以上是关于删除带有特殊字符的单词的主要内容,如果未能解决你的问题,请参考以下文章