【发布时间】:2009-09-16 23:51:26
【问题描述】:
我需要拆分一个字符串,假设“asdf aA asdfget aa uoiu AA”使用“aa”拆分,忽略大小写。 到
"asdf "
"asdfget "
"uoiu "
【问题讨论】:
-
Plus1 不使用真实单词但仍保持问题的连续性
我需要拆分一个字符串,假设“asdf aA asdfget aa uoiu AA”使用“aa”拆分,忽略大小写。 到
"asdf "
"asdfget "
"uoiu "
【问题讨论】:
使用string.Split 来实现这一点并不容易。 (好吧,除了为数组中的每个小写/大写字符指定拆分字符串的所有排列 - 我想你会同意的,这不是很优雅。)
但是,Regex.Split 应该可以很好地完成这项工作。
例子:
var parts = Regex.Split(input, "aa", RegexOptions.IgnoreCase);
【讨论】:
Strings.Split)...我真的会后悔改用 C# 吗?
如果你不关心大小写,那么最简单的做法是在使用拆分之前强制字符串全部大写或小写。
stringbits = datastring.ToLower().Split("aa")
如果您关心字符串中有趣位的大小写而不关心分隔符,那么我将使用 String.Replace 将所有分隔符强制为特定大小写(大写或小写,无关紧要),然后调用 String.Replace。使用分隔符的匹配大小写进行拆分。
strinbits = datastring.Replace("aA", "aa").Replace("AA", "aa").Split("aa")
【讨论】:
在您的算法中,您可以使用String.IndexOf 方法并将OrdinalIgnoreCase 作为StringComparison 参数传入。
【讨论】:
我的答案不如Noldorin's,但我会留下它,以便人们可以看到替代方法。这对于简单的拆分不太好,但如果您需要进行更复杂的解析,它会更加灵活。
using System.Text.RegularExpressions;
string data = "asdf aA asdfget aa uoiu AA";
string aaRegex = "(.+?)[aA]{2}";
MatchCollection mc = Regex.Matches(data, aaRegex);
foreach(Match m in mc)
{
Console.WriteLine(m.Value);
}
【讨论】:
这不是漂亮的版本,但也可以:
"asdf aA asdfget aa uoiu AA".Split(new[] { "aa", "AA", "aA", "Aa" }, StringSplitOptions.RemoveEmptyEntries);
【讨论】:
使用我的方法拆分
public static string[] Split(this string s,string word,StringComparison stringComparison)
{
List<string> tmp = new List<string>();
int wordSt;
s.IndexOf(word, 0, stringComparison);
while(s.IndexOf(word, 0, stringComparison) > -1)
{
wordSt = s.IndexOf(word, 0, stringComparison);
tmp.Add(s.Substring(0, wordSt));
s = s.Substring(wordSt + word.Length);
}
tmp.Add(s);
return tmp.ToArray();
}
【讨论】:
public static List<string> _Split(this string input,string[] splt)
{
List<string> _Result=new List<string>();
foreach(string _splt in splt)
{
if (splt.Count() == 1)
{
_Result.AddRange(Regex.Split(input, _splt, RegexOptions.IgnoreCase).ToList());
}
else
{
List<string> NewStr = Regex.Split(input, _splt, RegexOptions.IgnoreCase).ToList();
foreach(string _NewStr in NewStr)
{
List<string> NewSplt = splt.ToList();
NewSplt.Remove(_splt);
return _Split(_NewStr, NewSplt.ToArray());
}
}
}
return _Result;
}
然后像下面这样使用这个函数
public frmThematicConversation()
{
InitializeComponent();
string str = "a b c d e f g h a b c f a d c b f";
string[] splt = { "a", "b" };
List<string> _result = str._Split(splt);
}
【讨论】:
我编写的这个扩展方法取得了很好的成功,它使用.replace() 来查找和修复外壳。
你这样称呼它:
var result = source.Split(prefix, StringComparison.InvariantCultureIgnoreCase);
扩展方法定义如下。
public static string[] Split(this string source, string separator,
StringComparison comparison = StringComparison.CurrentCulture,
StringSplitOptions splitOptions = StringSplitOptions.None)
{
if (source is null || separator is null)
return null;
// Pass-through the default case.
if (comparison == StringComparison.CurrentCulture)
return source.Split(new string[] { separator }, splitOptions);
// Use Replace to deal with the non-default comparison options.
return source
.Replace(separator, separator, comparison)
.Split(new string[] { separator }, splitOptions);
}
注意:此方法处理我通常传递单个字符串分隔符的默认情况。
【讨论】:
Dim arr As String() = Strings.Split("asdf aA asdfget aa uoiu AA",
"aa" ,, CompareMethod.Text)
CompareMethod.Text 忽略大小写。
【讨论】:
基于@Noldorin 的回答,我做了这个扩展方法。
它接受多个分隔符字符串,并在您提供多个分隔符字符串时模仿string.Split(..) 的行为。它具有不变的('culture-unspecific')文化,当然会忽略案例。
/// <summary>
/// <see cref="string.Split(char[])"/> has no option to ignore casing.
/// This functions mimics <see cref="string.Split(char[])"/> but also ignores casing.
/// When called with <see cref="StringSplitOptions.RemoveEmptyEntries"/> <see cref="string.IsNullOrWhiteSpace(string)"/> is used to filter 'empty' entries.
/// </summary>
/// <param name="input">String to split</param>
/// <param name="separators">Array of separators</param>
/// <param name="options">Additional options</param>
/// <returns></returns>
public static IEnumerable<string> SplitInvariantIgnoreCase(this string input, string[] separators, StringSplitOptions options)
{
if (separators == null) throw new ArgumentNullException(nameof(separators));
if (separators.Length <= 0) throw new ArgumentException("Value cannot be an empty collection.", nameof(separators));
if (string.IsNullOrWhiteSpace(input)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(input));
// Build a regex pattern of all the separators this looks like aa|bb|cc
// The Pipe character '|' means alternative.
var regexPattern = string.Join("|", separators);
var regexSplitResult = Regex.Split(input, regexPattern, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
// NOTE To be honest - i don't know the exact behaviour of Regex.Split when it comes to empty entries.
// Therefore i doubt that filtering null values even matters - however for consistency i decided to code it in anyways.
return options.HasFlag(StringSplitOptions.RemoveEmptyEntries) ?
regexSplitResult.Where(c => !string.IsNullOrWhiteSpace(c))
: regexSplitResult;
}
【讨论】: