Разделение строки с указанной строкой без разделителя - PullRequest
0 голосов
/ 23 апреля 2020
Updated - When searched value is in middle

string text = "Trio charged over alleged $100m money laundering syndicate at Merrylands, Guildford West";
string searchtext= "charged over";
string[] fragments = text.Split(new string[] { searchtext }, StringSplitOptions.None);

    //Fragments
   //if [0] is blank searched text is in the beginning - searchedtext + [1]
  //if [1] is blank searched text is in the end - [0] + searched text
  // If searched text is in middle then both items has value - [0] + seachedtext + [1]

 //This loop will execute only two times because it can have maximum 2 values, issue will
 //come when searched value is in middle (loop should run 3 times) as for the searched value i have to apply differnt logic (like change background color of the text)
 // and dont change background color for head and tail
 //How do i insert searched value in middle of [0] and [1] ??

У меня есть строка без разделителя, которую я пытаюсь разделить на основе искомой строки. Мое требование - разбить строку на две части, одна часть содержит строку без текста поиска, а другая содержит текст поиска, как показано ниже -

 Original String - "Bitcoin ATMs Highlight Flaws in EU Money Laundering Rules"
    String 1 - Bitcoin ATMs Highlight Flaws in EU 
    String 2 - Money Laundering Rules

I have written below code it works for the above sample value, but it failed for 

Failed - Not returning String 1 and String 2, String is empty
string watch = " Money Laundering Rules Bitcoin ATMs Highlight Flaws in EU";
string serachetxt = "Money Laundering Rules";

Это работает -

List<string> matchedstr = new List<string>();
string watch = "Bitcoin ATMs Highlight Flaws in EU Money Laundering Rules";
string serachetxt = "Money Laundering Rules";

string compa = watch.Substring(0,watch.IndexOf(serachetxt)); //It returns "Bitcoin ATMs Highlight Flaws in EU"

matchedstr.Add(compa);
matchedstr.Add(serachetxt);

foreach(var itemco in matchedstr)
{

}

Ответы [ 4 ]

1 голос
/ 23 апреля 2020

Вы можете просто считать "Money Laundering Rules" разделителем. Затем вы можете написать

string[] result = watch.Split(new string[] { searchtext }, StringSplitOptions.None);

Затем вы можете снова добавить разделитель

string result1 = result[0];
string result2 = searchtext + result[1];
0 голосов
/ 25 апреля 2020

Вы можете попробовать это

        string text = "Trio charged over alleged $100m money laundering syndicate at Merrylands, Guildford West";
        string searchtext = "charged over";
        searchtextPattern =  "(?=" + searchtext + ")";

        string[] fragments= Regex.Split(text, searchtextPattern);
        //fargments will have two elements here
        // fragments[0] - "Trio"
        // fragments[1] - "charged over alleged $100m money laundering syndicate at Merrylands, Guildford West"

, теперь вы можете снова разделить фрагмент, в котором есть искомый текст, например, фрагменты [1]. см. код ниже

            var stringWithoutSearchText = fragments[1].Replace(searchtext, string.Empty);

Вам необходимо проверить, содержит ли каждый фрагмент текст для поиска или нет. Вы можете сделать это на своем фрагменте. добавить ниже проверить там

     foreach (var item in fragments)
     { 
        if (item.Contains(searchtext))
        { 
          string stringWithoutSearchText = item.Replace(searchtext, string.Empty);
        }
     }

Ссылка: { ссылка }

0 голосов
/ 24 апреля 2020

Вы можете написать свой собственный метод расширения для этого:

// Splits s at sep with sep included at beginning of each part except first
// return no more than numParts parts
public static IEnumerable<string> SplitsBeforeInc(this string s, string sep, int numParts = Int32.MaxValue)
    => s.Split(new[] { sep }, numParts, StringSplitOptions.None).Select((p,i) => i > 0 ? sep+p : p);

И использовать его с:

foreach(var itemco in watch.SplitsBeforeInc(watch, serachetxt, 2))

Вот тот же метод в не-LINQ версии:

// Splits s at sep with sep included at beginning of each part except first
// return no more than numParts parts
public static IEnumerable<string> SplitsBeforeInc(this string s, string sep, int numParts = Int32.MaxValue) {
    var startPos = 0;
    var searchPos = 0;
    while (startPos < s.Length && --numParts > 0) {
        var sepPos = s.IndexOf(sep, searchPos);
        sepPos = sepPos < 0 ? s.Length : sepPos;
        yield return s.Substring(startPos, sepPos - startPos);
        startPos = sepPos;
        searchPos = sepPos+sep.Length;
    }
    if (startPos < s.Length)
        yield return s.Substring(startPos);
}
0 голосов
/ 23 апреля 2020

Использовать string.Split.

string text = "Bitcoin ATMs Highlight Flaws in EU Money Laundering Rules";
string searchtext = "Money Laundering Rules";
string[] fragments = text.Split(new string[] { searchtext }, StringSplitOptions.None);

fragments будет равно:

[0] "Bitcoin ATMs Highlight Flaws in EU "
[1] ""

Везде, где есть разрыв между последовательными элементами массива, появляется строка поиска. Например:

string originaltext = string.Join(searchtext, fragments);

Расширенное описание поведения String.Split

Вот краткая таблица поведения string.Split при передаче строки.

| Input  | Split | Result Array       |
+--------+-------+--------------------+
| "ABC"  | "A"   | { "", "BC" }       |
| "ABC"  | "B"   | { "A", "C" }       |
| "ABC"  | "C"   | { "AB", "" }       |
| "ABC"  | "D"   | { "ABC" }          |
| "ABC"  | "ABC" | { "", "" }         |
| "ABBA" | "A"   | { "", "BB", "" }   |
| "ABBA" | "B"   | { "A", "", "A" }   |
| "AAA"  | "A"   | { "", "", "", "" } |
| "AAA"  | "AA"  | { "", "A" }        |

Если вы посмотрите на таблицу выше, каждое место, где в массиве была запятая (между двумя последовательными элементами в массиве), это место, где была найдена разделенная строка.

Если строка не была найдена, тогда в массиве результатов будет только один элемент (исходная строка).

Если в начале входной строки находится разделенная строка, то в качестве первого элемента массива результатов будет задана пустая строка. начало строки. Аналогично, если в конце строки найдена разделенная строка, в качестве последнего элемента массива результатов устанавливается пустая строка.

Кроме того, пустая строка включается между любыми последовательными вхождениями строки поиска. во входной строке.

В тех случаях, когда есть неоднозначные перекрывающиеся местоположения, в которых строка может быть найдена во входной строке: (например, разделение AAA на AA может быть разделено как AA | A или A | AA - где AA находится в позиции 0 или позиции 1 во входной строке), затем используется местоположение ранее . (например, AA | A, что приводит к { "", "A" }).

Опять же, инвариант заключается в том, что исходную строку всегда можно восстановить, соединив все фрагменты и поместив ровно одно вхождение искомого текста между элементами. Следующее всегда будет истинным:

string.Join(searchtext, fragments) == text

Если вы хотите только первое разделение ...

Вы можете объединить все результаты после первого объединения вместе, как это :

if (fragments.Length > 1) {
    fragments = new string[] { fragments[0], string.Join(searchtext, fragments.Skip(1)) };
}

... или более эффективный способ, используя String.IndexOf

Если вы просто хотите найти первое место текстовой строки поиска, используйте String.IndexOf, чтобы получить позиция первого вхождения искомого текста во входной строке.

Вот полная функция, которую вы можете использовать

private static bool TrySplitOnce(string text, string searchtext, out string beforetext, out string aftertext)
{
    int pos = text.IndexOf(searchtext);
    if (pos < 0) {
        // not found
        beforetext = null;
        aftertext = null;
        return false;
    } else {
        // found at position `pos`
        beforetext = text.Substring(0, pos); // may be ""
        aftertext = text.Substring(pos + searchtext.Length); // may be ""
        return true;
    }
}

Вы можете использовать ее для создания массива, если хотите.

использование:

string text = "red or white or blue";
string searchtext = "or";
if (TrySplitOnce(text, searchtext, out string before, out string after)) {
    Console.WriteLine("{0}*{1}", before, after);
    // output:
    //     red * white or blue
    string[] array = new string[] { before, searchtext, after };
    // array == { "red ", "or", " white or blue" };
    Console.WriteLine(string.Join("|", array));
    // output:
    //     red |or| white or blue  
} else {
    Console.WriteLine("Not found");
}

выход:

red * white or blue
red |or| white or blue
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...