【问题标题】:How Parsing string between [STX] and [ETX] using C# - Split/Append output using Regex or String Functions如何使用 C# 解析 [STX] 和 [ETX] 之间的字符串 - 使用正则表达式或字符串函数拆分/追加输出
【发布时间】:2010-09-27 19:33:03
【问题描述】:

语言 = C#.NET

任何介于 [STX] 和 [ETX] 之间的东西都必须被接受,其余的东西必须被拒绝。

string startparam = "[STX]";
string endparam = "[ETX]";

String str1 = "[STX]some string 1[ETX]"; //Option 1
String str2 = "sajksajsk [STX]some string 2 [ETX] saksla"; //Option 2
String str3 = "[ETX] dksldkls [STX]some string 3 [ETX]ds ds"; //Option 3
String str4 = "dksldkls [STX]some string 4.1[ETX]ds ds [STX] some string 4.2[ETX] jdskjd"; //Option 4

/* the various strings can be appended and converted to a single 
   string using string builder or treat them as different strings*/

ProcessString (string str , string startparam , string endparam)
{
   //What To Write here using RegEX or String Functions in c#

}

/* The output after passing these to a ProcessString () */     
/* Append Output To a TextBox or Append it to a String using For Loop.*/

/* Output Required */

some string 1 
some string 2
some string 3
some string 4.1 
some string 4.2

================================================ ===============================

编辑 2

Language = C#

string str = "
[STX]some string 1[ETX]
sajksajsk [STX]some string 2 [ETX] saksla
[ETX] dksldkls [STX]some string 3 [ETX]ds ds
dksldk[STX]ls [STX]some st[ETX]ring 4.1[ETX]ds ds [STX]some string 4.2[ETX] jdskjd";

如果字符串数组是单个字符串,我如何获得相同的输出

/* output */
some string 1 
some string 2
some string 3
some string 4.1 
some string 4.2


/*case 1*/ 
the above string can be "[STX] djkdsj [STX]dskd1[ETX] dsnds[ETX]" 
the output should be just "dskd1"

/*case 2*/ 
the above string can be "[STX] djkdsj [STX]dskd1[ETX] ddd" 
the output should be just "dskd1"

/*case 3*/ 
the above string can be " kdsj [STX]dskd1[ETX] dsnds[ETX]" 
the output should be just "dskd1"

/*case 4*/ 
the above string can be "[STX] djk[STX]dsj [STX]dskd2[ETX] ddd" 
the output should be just "dskd2"

The real problem comes when [STX] followed by [STX] i want to consider the newer [STX] and start string processing from the newer [STX] occurance. Eg. Case 2 above

================================================ ===============================

编辑 3:新请求

语言 = C#

如果我想要 [STX] 和 [STX] 之间的数据也可以这样做。

新的 RegEx 将在 1. [STX] 部分数据 [STX] 2. [STX]一些数据[ETX]

例如。

/* the above string can be */
"[STX] djk[STX]dsj [STX]dskd2[ETX] ddd" 
/* the output should be just */
djk
dsj
dskd2

由于 [STX] 意味着传输已经开始,所以我也想在 STX 之间提取数据。

【问题讨论】:

标签: c# regex parsing string


【解决方案1】:

这对我有用:

string[] sepValues = input.Split(new char[] {'\u0002', '\u0003'},
                                 StringSplitOptions.RemoveEmptyEntries);

【讨论】:

    【解决方案2】:
    (?<=\[STX\])(?:(?!\[STX\]).)*?(?=\[ETX\])
    

    匹配[STX][ETX] 之间的任何文本(换行符除外):

    (?<=\[STX\])  # Are we right after [STX]? If so,...
    (?:           # match 0 or more of the following:
     (?!\[STX\])  # (as long as it's not possible to match [STX] here)
     .            # exactly one character
     )*?          # repeat as needed until...
    (?=\[ETX\])   # there is a [ETX] ahead.
    

    这将始终与以下各项中的 somestring 匹配:

    blah blah [STX]somestring[ETX] blah blah
    [STX]somestring[ETX] blah [STX]somestring[ETX] (hey, two matches here!)
    [STX] not this! [STX]somestring[ETX] not this either! [ETX]
    blah [ETX] [STX]somestring[ETX] [STX] bla bla
    

    可以在 Jan Goyvaerts 的优秀正则表达式教程http://www.regular-expressions.info/lookaround.html 中找到有关正/负后向和前瞻断言(其中三个用于此正则表达式)的完整参考。

    【讨论】:

    • 我刚开始使用 RegEx,它很难理解,您能否进一步简化它的工作原理,一些有助于轻松理解 RegEx 的网络链接。
    • (?&lt;=XXX) 是肯定的lookbehind assertion。意思是“从当前位置向后看,看看那里有没有XXX”。
    【解决方案3】:

    试试这个:

    Regex regex = new Regex(@"\[STX\](.*?)\[ETX\]", RegexOptions.IgnoreCase);
    

    然后只需挑选组来获取标签之间的字符串

    【讨论】:

    • 这将在[STX] not this [STX] THIS! [ETX]等字符串中失败。
    • @Tim 这取决于你想要什么......如果你想要外部或内部之间的东西。
    • 他说他想要内在的。但是,他在答案中写了这个,而不是编辑他的问题......
    • @Tim 没看到(其实是我回答后才发的)
    【解决方案4】:

    编辑:为了满足您更新的要求,您应该使用这种利用环视的模式跳过所有 STX 组,除了最后一个后面有 ETX 的组:

    string pattern = @"(?<=\[STX])?.*\[STX]\s*(.+?)\s*\[ETX].*?";
    

    这是一个完整的例子:

    string input = @"[STX]some string 1[ETX]
    sajksajsk [STX]some string 2 [ETX] saksla
    [ETX] dksldkls [STX]some string 3 [ETX]ds ds
    dksldkls [STX]some string 4.1[ETX]ds ds [STX] some string 4.2[ETX] jdskjd
    [STX] djkdsj [STX]dskd1[ETX] dsnds[ETX]
    [STX] djkdsj [STX]dskd1[ETX] ddd
    kdsj [STX]dskd1[ETX] dsnds[ETX] 
    [STX] djk[STX]dsj [STX]dskd2[ETX] ddd";
    
    string pattern = @"(?<=\[STX])?.*\[STX]\s*(.+?)\s*\[ETX].*?";
    
    foreach(Match m in Regex.Matches(input, pattern))
    {
        // result will be in first group
        Console.WriteLine(m.Groups[1].Value);
    }
    

    我还在分组之间添加了\s* 以消除额外的空白。通过这样做,您不再需要使用 Trim(),正如我在下面之前的回复中所建议的那样。


    之前的回复

    这个模式应该适合:"\[STX](.+?)\[ETX]"

    请注意,左括号[ 必须进行转义,以防止它被解释为正则表达式中的字符类。右括号 ] 不需要转义。 (.+?) 是一个捕获组(由于括号),并且以非贪婪方式匹配至少一个字符(通过?)。通过非贪婪,它可以防止正则表达式引擎贪婪地匹配多个出现和内容,直到最后一个“[ETX]”出现。删除?,您将在str4 示例中看到我的意思。由于您的上一个示例多次出现,您可以使用Matches method

    string[] inputs =
    {
        "[STX]some string 1[ETX]",
        "sajksajsk [STX]some string 2 [ETX] saksla",
        "[ETX] dksldkls [STX]some string 3 [ETX]ds ds",
        "dksldkls [STX]some string 4.1[ETX]ds ds [STX] some string 4.2[ETX] jdskjd"
    };
    
    string pattern = @"\[STX](.+?)\[ETX]";
    
    foreach (string input in inputs)
    {
        Console.WriteLine("Input: " + input);
        foreach(Match m in Regex.Matches(input, pattern))
        {
            // result will be in first group
            Console.WriteLine(m.Groups[1].Value);
        }
    
          Console.WriteLine();
    }
    

    您可以考虑使用Trim() 修剪多余的空格 (m.Groups[1].Value.Trim())。可以在模式中实现,但不必要地使其复杂化。如果您需要忽略“STX”和“ETX”文本的大小写(如果它们不总是大写形式),请使用接受RegexOptions.IgnoreCase 的重载。

    【讨论】:

      猜你喜欢
      • 2016-12-11
      • 2017-12-30
      • 2022-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-23
      相关资源
      最近更新 更多