如何使用C#在[STX]和[ETX]之间解析字符串 - 使用正则表达式或字符串函数分割/追加输出

时间:2010-09-27 19:33:03

标签: c# regex parsing string

语言= 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之间提取数据。

4 个答案:

答案 0 :(得分:5)

这对我有用:

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

答案 1 :(得分:1)

(?<=\[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优秀正则表达式教程中可以找到关于正/负外观和前瞻断言(其中三个用于此正则表达式)的完整参考。

答案 2 :(得分:0)

试试这个:

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

然后选择该组以获取标签之间的字符串

答案 3 :(得分:0)

编辑以符合您更新的要求,您应该使用这种模式,利用环视功能跳过所有STX组,除了最后一个有ETX后的STX组:

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的重载。