搜索字符串并按找到的内容拆分原始字符串

时间:2017-05-26 16:18:34

标签: c# string split

我想知道是否有一种很好的方法来查找内容,并且还会根据找到的内容拆分结果,例如,如果我有字符串:

string str = "you androids don't exactly cover for each other in times of stress. 
i think you're right it would seem we lack a specific talent you humans possess
i believe it's called empathy"; 

和搜索字符串,例如:

var sList = new List {"for each other",  "talent", "you humans"};

通过原始字符串的吐出分隔找到的字符串的结果将是:

you androids don't exactly cover 
for each other 
in times of stress. i think you're right it would seem we lack a specific 
talent 
you humans  
possess i believe it's called empathy

如果相同的字符串在两个不同的搜索字符串中(这里):

var sList = new List {"for each other", "other in", "talent", "you humans", "you"};

正确的输出应为:

you 
androids don't exactly cover 
for each other
other in
times of stress. i think you're right it would seem we lack a specific 
talent 
you
you humans  
possess i believe it's called empathy

2 个答案:

答案 0 :(得分:1)

试试这个:

List<string> parts = new List<string> { str };
sList.ForEach(seperator => parts = parts
    .SelectMany(part => Regex.Match(part, "(.*) ?(\\b" + seperator + "\\b) ?(.*)|(.+)")
        .Groups
        .Cast<Group>()
        .Where(group => group.Success)
        .Select(group => group.Value)
        .Skip(1))
    .ToList());

parts = parts
    .Where(x => !string.IsNullOrWhiteSpace(x))
    .ToList();

输出:

you
androids don't exactly cover 
for each other
in times of stress. i think youre right it would seem we lack a specific 
talent
you
humans
possess i believe it's called empathy

Dotnet Fiddle Demo

答案 1 :(得分:0)

您可以使用正则表达式匹配字符串中的一组字符串,然后您需要考虑两者之间的间隙,调整重叠的匹配范围:

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Linq;

public class Program
{
    public static void Main()
    {
        string str = "you androids don't exactly cover for each other in times of stress. i think youre right it would seem we lack a specific talent you humans possess i believe it's called empathy"; 
        var sList = new List<string> {"for each other", "other in", "talent", "you humans", "you"};
        var chRangeMap = new bool[str.Length];
        for (var i = 0; i < chRangeMap.Length; ++i) chRangeMap[i] = false;

        var matchedTokenMap = sList
            .Select(i => "\\b" + Regex.Escape(i) + "\\b")
            .SelectMany(p => (new Regex(p)).Matches(str).OfType<Match>())
            .Cast<Match>()
            .Select(m => new 
                    { 
                        StartIndex = m.Index,
                        EndIndex = m.Index + m.Length,
                        Length = m.Length
                    })
            .Select(r => {
                for (var i = r.StartIndex; i < r.EndIndex; ++i) chRangeMap[i] = true;
                return r;
                });

        var fullTokenized = 
            matchedTokenMap.Concat(
                GetArrayRanges(chRangeMap, false)
                    .Select(r => new 
                            { 
                                StartIndex = r.Item1,
                                EndIndex = r.Item2,
                                Length = r.Item2 - r.Item1
                            })
            )
            .OrderBy(k => k.StartIndex).ThenBy(sk => sk.Length);

        foreach(var token in fullTokenized)
        {
            WriteTrimmed(str.Substring(token.StartIndex, token.Length));
        }
    }

    private static void WriteTrimmed(string str)
    {
        str = str.Trim();
        if (!string.IsNullOrWhiteSpace(str))
        {
            Console.WriteLine(str);
        }
    }

    private static IEnumerable<Tuple<int, int>> GetArrayRanges(bool[] array, bool seekValue)
    {
        int? rangeStart = null;

        for(var i = 0; i < array.Length; ++i)
        {
            if (array[i] == seekValue)
            {
                if (!rangeStart.HasValue)
                {
                    rangeStart = i;
                }
            }
            else
            {
                if (rangeStart.HasValue)
                {
                    yield return Tuple.Create(rangeStart.Value, i);
                    rangeStart = null;
                }
            }
        }

        if (rangeStart.HasValue)
        {
            yield return Tuple.Create(rangeStart.Value, array.Length);
        }
    }
}

DotNETFiddle of the code