C# 在c中使用正则表达式解析字符串到数组#
我目前正在制作一个c#应用程序,它从串口接收字符串,我需要解析这些数据,这样我就可以处理它了 通过C# 在c中使用正则表达式解析字符串到数组#,c#,regex,string-parsing,C#,Regex,String Parsing,我目前正在制作一个c#应用程序,它从串口接收字符串,我需要解析这些数据,这样我就可以处理它了 通过串行端口发送的字符串格式如下: 现在我想知道如何在*符号上将这个字符串分割成段, 我自己也做过几次尝试,但都没弄明白 我的尝试是: 这给了我: NTF,CTRL,SQL,OPEN,+,-66 NTF、CT RL、DBUSY ,开,+,-6 3. NTF,CT RL,DBUSY ,关闭NTF,CT RL,SQL,C 失去 我也尝试过: 但这给了我一个错误 我想要达到的目标: 格式化的字符串如下所示
串行端口发送的字符串格式如下:
现在我想知道如何在*
符号上将这个字符串分割成段,
我自己也做过几次尝试,但都没弄明白
我的尝试是:
这给了我:
NTF,CTRL,SQL,OPEN,+,-66
NTF、CT RL、DBUSY
,开,+,-6
3.
NTF,CT
RL,DBUSY
,关闭NTF,CT
RL,SQL,C
失去
我也尝试过:
但这给了我一个错误
我想要达到的目标:
格式化的字符串如下所示:
NTF,CTRL,SQL,OPEN,+,-66
NTF、CTRL、DBUSY、ON、+、-63
NTF、CTRL、DBUSY、OFF
NTF、CTRL、SQL、CLOSE
编辑:
我通过以下代码解决了问题:
SerialPort sp = (SerialPort)sender;
data += sp.ReadExisting().ToString();
string[] tmp = data.Split(new char[] {'\u0002','\u0003'}, StringSplitOptions.RemoveEmptyEntries);
foreach (string line in tmp)
{
if (line.Contains(",80") || line.Contains(",81") || line.Contains(",RXVCALL"))
{
COM_PORT_INFO_BOX.Text += line.Substring(1) + "\r\n";
data = "";
}
}
我知道你说“更喜欢使用正则表达式”,但这是使用字符串的更干净的IMHO。拆分:
string s = "*blablablab,blablabla,blablabla,blablabla*blablabla,blabalbal,blablabla*";
string[] results = s.Split(new [] {'*'}, StringSplitOptions.RemoveEmptyEntries);
结果:
String[] (2 items)
----------------------------
blablablab,blablabla,blablabla,blablabla
blablabla,blabalbal,blablabla
使用String.Split
时需要记住的一点是,字符串以分隔符开头或结尾,结果数组的开头和结尾将分别出现空条目。添加StringSplitOptions.RemoveEmptyEntries
参数将删除这些空条目,因此每对星号之间只剩下两个Sting。这对我在regexr.com上很有用
正则表达式的问题是,结尾“*”需要用作第一个条目的结尾和第二个条目的开头。但是因为它已经用于第一个,所以在第二个中被忽略
这就是我使用“\2”反向引用的原因
\2(.+?)(\*)
\2 -> backreference to the second group (\*)
(.+?) -> every character until a "*" is found
(\*) -> The character thats ending a single Entry
试试这个
([^\*](\.*)[^\*])*
它成功了
我认为逻辑上是正确的,我试了一下,结果吻合了
希望它能帮助你“preferly with regex”为什么?阅读string.Split
方法。你尝试过什么?结果如何?预期产量是多少?如果你想让别人努力回答String,请多问一个问题。Split()
不是什么新技术。它非常简单,除非你给它错误的输入,否则它不会搞砸。仔细检查您实际得到的字符串,确保它没有嵌入换行符或额外的星号。您的新问题是重复的,它还包括第一个星号之前和最后一个星号之后的字符串,例如,从“asdf*1*2*asdf”
中,您不仅会得到“1”
和“2”
但也包括前后的“asdf”
。目前还不确定OP在这种情况下的期望值,但标题中的“中间”表示可能不需要它。我尝试过这样做,并尝试在文本框中使用:data=sp.ReadExisting().ToString();string[]tmp=data.Split(新的[]{'*},StringSplitOptions.RemoveEmptyEntries);foreach(tmp中的字符串词){COM_PORT_INFO_BOX.Text+=word+“\r\n”;}但它仍然会导致我在诸如NTF、CTRL、SQL、OPEN、+、-66 NTF、CTRL、DBUSY、ON、+、-63 NTF、CTRL、DBUSY、OFF NTF、CTRL、SQL、,C lose结束符在CYou必须有一些嵌入的空格或控制字符后分开。这与string.Split没有任何关系,使用正则表达式,您的结果不会有任何不同。我将使用调试器更仔细地查看这些字符,看看是否可以将它们过滤掉。@Giovannielegrand您在这里写的内容与您提出的问题根本不匹配。你能用确切的例子更新你的问题吗?提供的答案对您的blabla
字符串有效。原因是:\2?为每个正则表达式添加了解释,没有必要使用正则表达式,所以我投了反对票。我看不到反对票的理由,因为我使用了正则表达式,因为主题是“如何使用正则表达式找到“”和“”之间的值?”@NikyBrettschneider:有了这些问题,你不能只看问题的表面价值,因为提问的人往往不能正确地表述他们的问题。无论如何,你没有解决这个问题。看看这个正则表达式的实际功能。因为我怀疑它是否如你所期望的那样有效。我已经试过了,但是在尝试使用它的时候,它已经给了我一个错误:无法识别的转义sequence@GiovanniLeGrand:您不应该使用此答案,但如果您确实这样做了,您必须确保使用C#的特殊字符串文字:@([^\*](\.*)[^[\*])*”
(注意开头的@).我给你的解决方案是C#请在我给你的链接上试试
String[] (2 items)
----------------------------
blablablab,blablabla,blablabla,blablabla
blablabla,blabalbal,blablabla
\2(.+?)(\*)
\2 -> backreference to the second group (\*)
(.+?) -> every character until a "*" is found
(\*) -> The character thats ending a single Entry
([^\*](\.*)[^\*])*
[^\*] = match any character which is not *
(\.*) = match any character
so the regex explanation is
at first match any character that is not *, then match any character that does not ends with *