Что Regex может лишить, например. "note:" и "firstName:" слева от строки? - PullRequest
2 голосов
/ 01 июня 2010

Мне нужно убрать «ярлык» с передней части струн, например,

примечание: это примечание

необходимо вернуть:

примечание

и

это записка

Я создал следующий пример кода, но у меня проблемы с регулярными выражениями.

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

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

namespace TestRegex8822
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> lines = new List<string>();
            lines.Add("note: this is a note");
            lines.Add("test:    just a test");
            lines.Add("test:\t\t\tjust a test");
            lines.Add("firstName: Jim"); //"firstName" IS a label because it does NOT contain a space
            lines.Add("She said this to him: follow me."); //this is NOT a label since there is a space before the colon
            lines.Add("description: this is the first description");
            lines.Add("description:this is the second description"); //no space after colon
            lines.Add("this is a line with no label");

            foreach (var line in lines)
            {
                Console.WriteLine(StringHelpers.GetLabelFromLine(line));
                Console.WriteLine(StringHelpers.StripLabelFromLine(line));
                Console.WriteLine("--");
                //note
                //this is a note
                //--
                //test
                //just a test
                //--
                //test
                //just a test
                //--
                //firstName
                //Jim
                //--
                //
                //She said this to him: follow me.
                //--
                //description
                //this is the first description
                //--
                //description
                //this is the first description
                //--
                //
                //this is a line with no label
                //--

            }
            Console.ReadLine();
        }
    }

    public static class StringHelpers
    {
        public static string GetLabelFromLine(this string line)
        {
            string label = line.GetMatch(@"^?:(\s)"); //???????????????
            if (!label.IsNullOrEmpty())
                return label;
            else
                return "";
        }

        public static string StripLabelFromLine(this string line)
        {
            return ...//???????????????
        }

        public static bool IsNullOrEmpty(this string line)
        {
            return String.IsNullOrEmpty(line);
        }
    }

    public static class RegexHelpers
    {
        public static string GetMatch(this string text, string regex)
        {
            Match match = Regex.Match(text, regex);
            if (match.Success)
            {
                string theMatch = match.Groups[0].Value;
                return theMatch;
            }
            else
            {
                return null;
            }
        }
    }
}

Добавлена ​​

@ Keltex, я включил вашу идею следующим образом, но она не соответствует ни одному тексту (все записи пустые), что мне нужно настроить в регулярном выражении?

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

namespace TestRegex8822
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> lines = new List<string>();
            lines.Add("note: this is a note");
            lines.Add("test:    just a test");
            lines.Add("test:\t\t\tjust a test");
            lines.Add("firstName: Jim"); //"firstName" IS a label because it does NOT contain a space
            lines.Add("first name: Jim"); //"first name" is not a label because it contains a space
            lines.Add("description: this is the first description");
            lines.Add("description:this is the second description"); //no space after colon
            lines.Add("this is a line with no label");

            foreach (var line in lines)
            {
                LabelLinePair llp = line.GetLabelLinePair();
                Console.WriteLine(llp.Label);
                Console.WriteLine(llp.Line);
                Console.WriteLine("--");
            }
            Console.ReadLine();
        }
    }

    public static class StringHelpers
    {
        public static LabelLinePair GetLabelLinePair(this string line)
        {
            Regex regex = new Regex(@"(?<label>.+):\s*(?<text>.+)");
            Match match = regex.Match(line); 
            LabelLinePair labelLinePair = new LabelLinePair();
            labelLinePair.Label = match.Groups["label"].ToString();
            labelLinePair.Line = match.Groups["line"].ToString();
            return labelLinePair;
        }
    }

    public class LabelLinePair
    {
        public string Label { get; set; }
        public string Line { get; set; }
    }

}

РЕШИТЬ:

Хорошо, я заставил его работать, плюс добавил небольшой хак, чтобы позаботиться о ярлыках с пробелами, и это именно то, что я хотел, СПАСИБО!

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

namespace TestRegex8822
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> lines = new List<string>();
            lines.Add("note: this is a note");
            lines.Add("test:    just a test");
            lines.Add("test:\t\t\tjust a test");
            lines.Add("firstName: Jim"); //"firstName" IS a label because it does NOT contain a space
            lines.Add("first name: Jim"); //"first name" is not a label because it contains a space
            lines.Add("description: this is the first description");
            lines.Add("description:this is the second description"); //no space after colon
            lines.Add("this is a line with no label");
            lines.Add("she said to him: follow me");

            foreach (var line in lines)
            {
                LabelLinePair llp = line.GetLabelLinePair();
                Console.WriteLine(llp.Label);
                Console.WriteLine(llp.Line);
                Console.WriteLine("--");
            }
            Console.ReadLine();
        }
    }

    public static class StringHelpers
    {
        public static LabelLinePair GetLabelLinePair(this string line)
        {
            Regex regex = new Regex(@"(?<label>.+):\s*(?<text>.+)");
            Match match = regex.Match(line); 
            LabelLinePair llp = new LabelLinePair();
            llp.Label = match.Groups["label"].ToString();
            llp.Line = match.Groups["text"].ToString();

            if (llp.Label.IsNullOrEmpty() || llp.Label.Contains(" "))
            {
                llp.Label = "";
                llp.Line = line;
            }

            return llp;
        }

        public static bool IsNullOrEmpty(this string line)
        {
            return String.IsNullOrEmpty(line);
        }
    }

    public class LabelLinePair
    {
        public string Label { get; set; }
        public string Line { get; set; }
    }

}

Ответы [ 3 ]

5 голосов
/ 01 июня 2010

Разве вы не можете просто разбить строку на первое двоеточие или, если нет двоеточия, нет метки?

public static class StringHelpers 
{ 
    public static string GetLabelFromLine(this string line) 
    { 
         int separatorIndex = line.IndexOf(':');
         if (separatorIndex > 0)
         {
            string possibleLabel = line.Substring(0, separatorIndex).Trim();
            if(possibleLabel.IndexOf(' ') < 0) 
            {
                return possibleLabel;
            }
         }
         else
         {
            return string.Empty;
         }        
     } 

    public static string StripLabelFromLine(this string line) 
    { 
        int separatorIndex = line.IndexOf(':');
         if (separatorIndex > 0)
         {
            return line.Substring(separatorIndex + 1, 
                   line.Length - separatorIndex - 1).Trim();
         }
         else
         {
            return line;
         }      
    } 

    public static bool IsNullOrEmpty(this string line) 
    { 
        return String.IsNullOrEmpty(line); 
    } 
} 
3 голосов
/ 01 июня 2010

Вероятно, это будет выглядеть так:

Regex myreg = new Regex(@"(?<label>.+):\s*(?<text>.+)");

Match mymatch = myreg.Match(text); 

if(mymatch.IsMatch) 
{ 
    Console.WriteLine("label: "+mymatch.Groups["label"]); 
    Console.WriteLine("text: "+mymatch.Groups["text"]); 
}

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

1 голос
/ 01 июня 2010

Это регулярное выражение работает ( смотрите его в действии на Рубулярном ):

(?: *([^:\s]+) *: *)?(.+)

Захватывает метку, если она есть, в \1, а тело в \2.

В нем достаточно припусков для пробелов, поэтому метки могут иметь отступ и т. Д.

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