簡體   English   中英

在同一行中提取多個子字符串

[英]Extract multiple substring in the same line

我正在嘗試構建一個 logparser,但我被卡住了。 現在我的程序通過一個目錄中的多個文件並逐行讀取所有文件。 我能夠識別我正在尋找的子字符串“fct=”,並使用分隔符提取“=”旁邊的值,但我注意到當我有一行超過一個“fct=”時,它沒有看到它。

所以我重新啟動我的代碼,我找到了一種方法來獲取 fct= 在同一行中使用將索引放在列表中的擴展方法的所有出現的索引位置,但我不知道如何使用此列表來獲取值在“=”旁邊並使用我的分隔符。

如何在知道“fct=”的開始位置和所需值末尾的分隔符的情況下提取“=”旁邊的值?

我從 C# 開始,所以如果我可以給你更多信息,請告訴我。 謝謝,

這是我想要解析的示例:

<dat>FCT=10019,XN=KEY,CN=ROHWEPJQSKAUMDUC FCT=666</dat></logurl>
<dat>XN=KEY,CN=RTU FCT=4515</dat></logurl>
<dat>XN=KEY,CN=RT</dat></logurl>

我想檢索 10019,666 和 4515。

namespace LogParserV1
{
class Program
{

    static void Main(string[] args)
    {

        int counter = 0;
        string[] dirs = Directory.GetFiles(@"C:/LogParser/LogParserV1", "*.txt");
        string fctnumber;
        char[] enddelimiter = { '<', ',', '&', ':', ' ', '\\', '\'' };

        foreach (string fileName in dirs)
        {
            StreamReader sr = new StreamReader(fileName);

            {
                String lineRead;
                while ((lineRead = sr.ReadLine()) != null)
                {

                    if (lineRead.Contains("fct="))
                    {
                        List<int> list = MyExtensions.GetPositions(lineRead, "fct");
                        //int start = lineRead.IndexOf("fct=") + 4;
                       // int end = lineRead.IndexOfAny(enddelimiter, start);
                        //string result = lineRead.Substring(start, end - start);

                        fctnumber = result;

                        //System.Console.WriteLine(fctnumber);
                        list.ForEach(Console.WriteLine);
                    }
                    // affiche tout les ligne System.Console.WriteLine(lineRead);
                    counter++;
                }
                System.Console.WriteLine(fileName);

                sr.Close();
            }
        }

        // Suspend the screen.  
        System.Console.ReadLine();

    }
}
}


namespace ExtensionMethods
{
public  class MyExtensions
{
    public static List<int> GetPositions(string source, string searchString)
    {
        List<int> ret = new List<int>();
        int len = searchString.Length;
        int start = -len;
        while (true)
        {
            start = source.IndexOf(searchString, start + len);
            if (start == -1)
            {
                break;
            }
            else
            {
                ret.Add(start);
            }
        }
        return ret;
    }
    }
}

您可以通過使用Regex模式匹配來大大簡化您的代碼。

以下模式: (?<=FCT=)[0-9]*將匹配任何以FCT=的數字組。

試試看

這使我們能夠執行以下操作:

string input = "<dat>FCT=10019,XN=KEY,CN=ROHWEPJQSKAUMDUC FCT=666</dat></logurl>...";
string pattern = "(?<=FCT=)[0-9]*";
var values = Regex.Matches(input, pattern).Cast<Match>().Select(x => x.Value);

我已經用你的數據測試了這個解決方案,它給了我預期的結果(10019,666 和 4515)

string data = @"<dat>FCT=10019,XN=KEY,CN=ROHWEPJQSKAUMDUC FCT=666</dat></logurl>
                <dat>XN=KEY,CN=RTU FCT=4515</dat></logurl>
                <dat>XN=KEY,CN=RT</dat></logurl>";

char[] delimiters = { '<', ',', '&', ':', ' ', '\\', '\'' };

Regex regex = new Regex("fct=(.+)", RegexOptions.IgnoreCase);

var values = data.Split(delimiters).Select(x => regex.Match(x).Groups[1].Value);
values = values.Where(x => !string.IsNullOrWhiteSpace(x));

values.ToList().ForEach(Console.WriteLine);  

我希望我的解決方案會有所幫助,讓我知道。

下面的代碼可用於提取文本中帶有 linq 的重復單詞

string text = "Hi Naresh, How are you. You will be next Super man";
    IEnumerable<string> strings = text.Split(' ').ToList();
    var result = strings.AsEnumerable().Select(x => new {str = Regex.Replace(x.ToLowerInvariant(), @"[^0-9a-zA-Z]+", ""), count = Regex.Matches(text.ToLowerInvariant(), @"\b" + Regex.Escape(Regex.Replace(x.ToLowerInvariant(), @"[^0-9a-zA-Z]+", "")) + @"\b").Count}).Where(x=>x.count>1).GroupBy(x => x.str).Select(x => x.First());
    foreach(var item in result)
    {
        Console.WriteLine(item.str +" = "+item.count.ToString());
    }

您可以按 string[] 分割該行

char[] enddelimiter = { '<', ',', '&', ':', ' ', '\\', '\'' };
while ((lineRead = sr.ReadLine()) != null)
            {
               string[] parts1 = lineRead.Split(new string[] { "fct=" },StringSplitOptions.None);

                if(parts1.Length > 0)
        {
            foreach(string _ar in parts1)
            {
                if(!string.IsNullOrEmpty(_ar))
                {
                    if(_ar.IndexOfAny(enddelimiter) > 0)
                    {
                        MessageBox.Show(_ar.Substring(0, _ar.IndexOfAny(enddelimiter)));
                    }
                    else
                    {
                        MessageBox.Show(_ar);
                    }
                }
            }
        }
     }

與往常一樣,將問題分解成更小的部分。 看看以下方法是否有任何幫助。 將它與您的代碼聯系起來是一種練習。

private const string Prefix = "fct=";

//make delimiter look up fast
private static HashSet<char> endDelimiters = 
    new HashSet<char>(new [] { '<', ',', '&', ':', ' ', '\\', '\'' });

private static string[] GetAllFctFields(string line) =>
    line.Split(new string[] { Prefix });

private static bool TryGetValue(string delimitedString, out string value)
{
    var buffer = new StringBuilder(delimitedString.Length);

    foreach (var c in delimitedString)
    {
        if (endDelimiters.Contains(c)) 
            break;

        buffer.Append(c);
    }

    //I'm assuming that no end delimiter is a format error.
    //Modify according to requirements
    if (buffer.Length == delimitedString.Length) 
    {
        value = null;
        return false;
    }

    value = buffer.ToString();
    return true;
}

就像是 :

class Program
{
    static void Main(string[] args)
    {
        char[] enddelimiter = { '<', ',', '&', ':', ' ', '\\', '\'' };
        var fct = "fct=";

        var lineRead = "fct=value1,useless text fct=vfct=alue2,fct=value3";

        var values = new List<string>();
        int start = lineRead.IndexOf(fct);
        while(start != -1)
        {
            start += fct.Length;
            int end = lineRead.IndexOfAny(enddelimiter, start);
            if (end == -1)
                end = lineRead.Length;
            string result = lineRead.Substring(start, end - start);
            values.Add(result);
            start = lineRead.IndexOf(fct, end);
        }
        values.ForEach(Console.WriteLine);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM