gpt4 book ai didi

c# - 使用 .NET Micro Framework,为什么我的正则表达式匹配失败?

转载 作者:太空宇宙 更新时间:2023-11-03 13:03:47 25 4
gpt4 key购买 nike

我正在为在 Netduino 上运行的 .net Micro Framework 4.3 开发一个小型网络命令解释器。我使用正则表达式来解析通过流套接字从网络到达的用户输入。命令格式如下:

<T1,0,CommandVerb=Payload>

这是一个设备地址,一个可以是任何整数的事务 ID,一个命令动词,后跟一个等号和任何文本。整个内容由尖括号分隔,很像 XML 标记,有助于解析。

这是我使用的正则表达式:

    /*
* Regex matches command strings in format "<Dn,TT,CommandVerb=Payload>
* D is the Device class
* n is the device index
* TT is a numeric transaction ID of at least 1 digits.
* CommandVerb is, obviously, the command verb ;-)
* Payload is optional and is used to supply any parameter values to the command.
*
* N.B. Micro Framework doesn't support named captures and will throw exceptions if they are used.
*/

const string CommandRegex = @"<(\w\d),(\d+),([A-Za-z]\w+)(=((\d+)|(.+)))?>";
static readonly Regex Parser = new Regex(CommandRegex);

此表达式旨在梳理命令的各个部分,以便我可以在代码中轻松访问它们。最后一部分(=((\d+)|(.+)))?区分数字有效载荷和文本有效载荷,或者根本没有有效载荷。

这对我来说效果很好,并且在 ReSharper 的正则表达式验证器中验证正常。这是我希望得到的输出(我认为这与您从完整的 NetFX 中获得的结果略有不同,我必须通过反复试验来解决这个问题):

        /* Command with numeric payload has the following groups
* Group[0] contains [<F1,234,Move=12345>]
* Group[1] contains [F1]
* Group[2] contains [234]
* Group[3] contains [Move]
* Group[4] contains [=12345]
* Group[5] contains [12345]
* Group[6] contains [12345]
* -----
* Command with text payload has the following groups:
* Group[0] contains [<F1,234,Nickname=Fred>]
* Group[1] contains [F1]
* Group[2] contains [234]
* Group[3] contains [Nickname]
* Group[4] contains [=Fred]
* Group[5] contains [Fred]
* Group[7] contains [Fred]
* -----
* Command with verb only (no payload) produces these groups:
* Group[0] contains [<F1,234,Stop>]
* Group[1] contains [F1]
* Group[2] contains [234]
* Group[3] contains [Stop]
*/

...它确实是这样工作的。直到我尝试将 URL 作为有效负载传递为止。一旦我的有效负载字符串中有一个点 (.),正则表达式就会中断,我实际上会返回第三种形式,它显然认为根本没有有效负载。例如:

<W1,0,HttpPost=http://deathstar.com/route>

我期望返回的是“带有文本有效负载的命令”结果,但我实际返回的是“没有有效负载的命令”结果。如果我去掉点,它就会按照我的预期进行解析,并且我得到“带有文本有效负载的命令”。一旦我把点放回去,然后(讽刺地).+似乎不再匹配。

再次注意:这在 ReSharper 的正则表达式验证器中正确验证并且似乎按预期在普通“桌面”框架上工作,但在 .NET Micro Framework 中不起作用。 Micro Framework 正则表达式实现是完整版本的一个子集,但关于什么应该工作和什么不工作的文档几乎不存在。

我不明白为什么.+与其中带点的文本不匹配。谁能看出它为什么不起作用?

更新 1 - 添加了诊断

这是输出:

[Cmd Processor     ] Parser matched 8 groups
[Cmd Processor ] Group[0]: <W1,0,HttpPost=http://deat
[Cmd Processor ] Group[1]: W1
[Cmd Processor ] Group[2]: 0
[Cmd Processor ] Group[3]: HttpPost
A first chance exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll

所以不是Group[4]为空,它抛出一个 ArgumentOutOfRangeException对于那个索引器,即使有 8 个组。另外,Group[0]被神秘地截断了。嗯……

更新 2 - 改进了诊断

根据@Shar1er80 的回答,我将此诊断方法添加到我的代码中:

    [Conditional("DEBUG")]
static void PrintMatches(Match match)
{
if (!match.Success)
{
Dbg.Trace("No match", Source.CommandProcessor);
return;
}
Dbg.Trace("Parser matched "+match.Groups.Count + " groups", Source.CommandProcessor);
for (int i = 0; i < match.Groups.Count; i++)
{
string value;
try
{
var group = match.Groups[i];
value = group == null ? "null group" : group.Value ?? "null value";
}
catch (Exception ex)
{
value = "threw " + ex.GetType() + " " + ex.Message??string.Empty;
}
Dbg.Trace(" Groups[" + i + "]: " + value, Source.CommandProcessor);
}
}

测试输入<W1,0,HttpPost=http://deathstar.com>输出是:

[Cmd Processor     ] Parser matched 8 groups
[Cmd Processor ] Groups[0]: <W1,0,HttpPost=http://deaths
[Cmd Processor ] Groups[1]: W1
[Cmd Processor ] Groups[2]: 0
[Cmd Processor ] Groups[3]: HttpPost
A first chance exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll
[Cmd Processor ] Groups[4]: threw System.ArgumentOutOfRangeException Exception was thrown: System.ArgumentOutOfRangeException
A first chance exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll
[Cmd Processor ] Groups[5]: threw System.ArgumentOutOfRangeException Exception was thrown: System.ArgumentOutOfRangeException
A first chance exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll
[Cmd Processor ] Groups[6]: threw System.ArgumentOutOfRangeException Exception was thrown: System.ArgumentOutOfRangeException
A first chance exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll
[Cmd Processor ] Groups[7]: threw System.ArgumentOutOfRangeException Exception was thrown: System.ArgumentOutOfRangeException
A first chance exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll

显然这是不对的,因为报告了 8 个匹配项,但尝试访问有关 Groups[3] 的任何内容都会引发异常。异常的堆栈跟踪是: System.String::子字符串 系统.Text.RegularExpressions.Capture::get_Value TA.NetMF.WeatherServer.CommandParser::PrintMatches TA.NetMF.WeatherServer.CommandParser::ParseCommand [剪]

我有opened an issue针对 .NET MicroFramework

最佳答案

点匹配一切。“(=((\d+)|(.+)))?>”方法1. 创建一个标记表达式(尾随“?”表示它是可选的)。2.它必须以等号开头,并且包含2.1.一个整数,或2.2.任何大小的东西。

2.2 将匹配表达式的其余部分,无论它是什么。

然后,当需要匹配结尾的结束符“>”时,如果“=”后面的不是整数,则缓冲区中将没有任何内容。因此,不匹配。

也许你可以尝试像下面这样的东西代替最后一部分:

“(=([^>]+))?>”。

关于c# - 使用 .NET Micro Framework,为什么我的正则表达式匹配失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31502055/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com