【发布时间】:2009-01-07 19:05:05
【问题描述】:
对于这个问题的希望在 30 秒内获得答案的部分,我专门寻找 C#
但在一般情况下,去除任何语言中的标点符号的最佳方法是什么?
我应该补充:理想情况下,解决方案不需要您列举所有可能的标点符号。
【问题讨论】:
-
不同的语言实际上是不同的,我认为您所问的问题没有答案。您可以询问特定的语言,或者哪种语言最适合这种操作。
对于这个问题的希望在 30 秒内获得答案的部分,我专门寻找 C#
但在一般情况下,去除任何语言中的标点符号的最佳方法是什么?
我应该补充:理想情况下,解决方案不需要您列举所有可能的标点符号。
【问题讨论】:
new string(myCharCollection.Where(c => !char.IsPunctuation(c)).ToArray());
【讨论】:
!char.IsSymbol(c)验证。仅作记录
为什么不简单:
字符串 s = "sxrdct?fvzguh,bij."; var sb = new StringBuilder(); foreach (char c in s) { if (!char.IsPunctuation(c)) sb.Append(c); } s = sb.ToString();RegEx 的使用通常比简单的字符操作要慢。那些 LINQ 操作对我来说看起来有点矫枉过正。而且你不能在 .NET 2.0 中使用这样的代码...
【讨论】:
描述意图、最容易阅读 (恕我直言) 和最佳表现:
s = s.StripPunctuation();
实施:
public static class StringExtension
{
public static string StripPunctuation(this string s)
{
var sb = new StringBuilder();
foreach (char c in s)
{
if (!char.IsPunctuation(c))
sb.Append(c);
}
return sb.ToString();
}
}
这是使用 Hades32 的算法,这是发布的一堆中表现最好的。
【讨论】:
假设“最好”意味着“最简单”,我建议使用类似这样的内容:
String stripped = input.replaceAll("\\p{Punct}+", "");
此示例适用于 Java,,但所有足够现代的正则表达式引擎都应支持此(或类似的东西)。
编辑:Unicode-Aware 版本是这样的:
String stripped = input.replaceAll("\\p{P}+", "");
第一个版本只查看 ASCII 中包含的标点符号。
【讨论】:
Punct 类,但它有 P
您可以使用 regex.replace 方法:
replace(YourString, RegularExpressionWithPunctuationMarks, Empty String)
由于这会返回一个字符串,因此您的方法将如下所示:
string s = Regex.Replace("Hello!?!?!?!", "[?!]", "");
如果你愿意,你可以用更复杂的东西替换“[?!]”:
(\p{P})
这应该可以找到任何标点符号。
【讨论】:
这个帖子太老了,但如果我不发布更优雅的 (IMO) 解决方案,那就太失职了。
string inputSansPunc = input.Where(c => !char.IsPunctuation(c)).Aggregate("", (current, c) => current + c);
这是没有 WTF 的 LINQ。
【讨论】:
基于 GWLlosa 的想法,我能够想出极其丑陋但有效的方法:
string s = "cat!"; s = s.ToCharArray().ToList<char>() .Where<char>(x => !char.IsPunctuation(x)) .Aggregate<char, string>(string.Empty, new Func<string, char, string>( delegate(string s, char c) { return s + c; }));
【讨论】:
最简单的方法是使用 string.replace
我想的另一种方式是 regex.replace 并在其中包含所有适当的标点符号的正则表达式。
【讨论】:
这是使用 linq 的一种稍微不同的方法。我喜欢 AviewAnew 的,但这避免了聚合
string myStr = "Hello there..';,]';';., Get rid of Punction";
var s = from ch in myStr
where !Char.IsPunctuation(ch)
select ch;
var bytes = UnicodeEncoding.ASCII.GetBytes(s.ToArray());
var stringResult = UnicodeEncoding.ASCII.GetString(bytes);
【讨论】:
IEnumerable<char> 到数组到字节到字符串的转换,为什么不只是new String(s.ToArray())?或者这就是新字符串在引擎盖下的作用?
如果你想用它来标记文本,你可以使用:
new string(myText.Select(c => char.IsPunctuation(c) ? ' ' : c).ToArray())
【讨论】:
对于任何想通过 RegEx 执行此操作的人:
这段代码显示了完整的正则表达式替换过程,并给出了一个示例正则表达式,它只在字符串中保留字母、数字和空格 - 用空字符串替换所有其他字符:
//Regex to remove all non-alphanumeric characters
System.Text.RegularExpressions.Regex TitleRegex = new
System.Text.RegularExpressions.Regex("[^a-z0-9 ]+",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
string ParsedString = TitleRegex.Replace(stringToParse, String.Empty);
return ParsedString;
【讨论】:
我遇到了同样的问题,并且担心每次检查都调用 IsPunctuation 会影响性能。
我发现了这个帖子:http://www.dotnetperls.com/char-ispunctuation。
跨界:char.IsPunctuation 还在 ASCII 之上处理 Unicode。 该方法匹配一堆字符,包括控制字符。顾名思义,这种方法既繁重又昂贵。
最重要的是,我最终没有选择它,因为它对我的 ETL 流程的性能影响。
我选择了 dotnetperls 的自定义实现。
仅供参考,这里是从前面的答案中推导出来的一些代码,用于获取所有标点符号(不包括控制符号)的列表:
var punctuationCharacters = new List<char>();
for (int i = char.MinValue; i <= char.MaxValue; i++)
{
var character = Convert.ToChar(i);
if (char.IsPunctuation(character) && !char.IsControl(character))
{
punctuationCharacters.Add(character);
}
}
var commaSeparatedValueOfPunctuationCharacters = string.Join("", punctuationCharacters);
Console.WriteLine(commaSeparatedValueOfPunctuationCharacters);
干杯, 安德鲁
【讨论】:
$newstr=ereg_replace("[[:punct:]]",'',$oldstr);
【讨论】:
对于长字符串我使用这个:
var normalized = input
.Where(c => !char.IsPunctuation(c))
.Aggregate(new StringBuilder(),
(current, next) => current.Append(next), sb => sb.ToString());
性能比使用字符串连接好得多(尽管我同意它不太直观)。
【讨论】:
这是从用户给出的字符串中删除标点符号的简单代码
import string
strs = str(input('Enter your string:'))
for c in string.punctuation:
strs= strs.replace(c,"")
print(f"\n Your String without punctuation:{strs}")
【讨论】:
#include<string>
#include<cctype>
using namespace std;
int main(int a, char* b[]){
string strOne = "H,e.l/l!o W#o@r^l&d!!!";
int punct_count = 0;
cout<<"before : "<<strOne<<endl;
for(string::size_type ix = 0 ;ix < strOne.size();++ix)
{
if(ispunct(strOne[ix]))
{
++punct_count;
strOne.erase(ix,1);
ix--;
}//if
}
cout<<"after : "<<strOne<<endl;
return 0;
}//main
【讨论】: