C#RegEx - 只获取字符串中的第一个匹配项

时间:2014-07-22 21:06:32

标签: c# regex

我有一个如下所示的输入字符串:

level=<device[195].level>&name=<device[195].name>

我想创建一个RegEx来解析每个<device>代码,例如,我希望我的输入字符串中匹配两个项目:<device[195].level>和{{ 1}}。

到目前为止,我对这种模式和代码运气不错,但它总是发现两个设备标签都是一个匹配:

<device[195].name>

结果是var pattern = "<device\\[[0-9]*\\]\\.\\S*>"; Regex rgx = new Regex(pattern); var matches = rgx.Matches(httpData); 将包含值为matches

的单个结果

我猜测必须有办法终止&#39;模式,但我不确定它是什么。

5 个答案:

答案 0 :(得分:6)

使用non-greedy quantifiers

<device\[\d+\]\.\S+?>

另外,使用逐字字符串来转义正则表达式,它使它们更具可读性:

var pattern = @"<device\[\d+\]\.\S+?>";

作为旁注,我想在你的情况下使用\w代替\S会更符合你的意图,但我离开了\S因为我不能知道那个。

答案 1 :(得分:3)

我想创建一个RegEx来解析每个<device>标记

I'd expect two items to be matched from my input string: 
   1. <device[195].level>
   2. <device[195].name>

这应该有效。从索引1获取匹配的组

(<device[^>]*>)

Live demo

程序中使用的字符串文字:

@"(<device[^>]*>)"

答案 2 :(得分:3)

取决于您需要匹配多少角度块的结构,但您可以

"\\<device.+?\\>"

答案 3 :(得分:2)

更改重复运算符并使用\w代替\S

var pattern = @"<device\[[0-9]+\]\.\w+>";

String s = @"level=<device[195].level>&name=<device[195].name>";
foreach (Match m in Regex.Matches(s, @"<device\[[0-9]+\]\.\w+>"))
         Console.WriteLine(m.Value);

输出

<device[195].level>
<device[195].name>

答案 4 :(得分:1)

使用命名匹配组并创建linq实体投影。将有两个匹配,从而将各个项目分开:

string data = "level=<device[195].level>&name=<device[195].name>";

string pattern = @"
(?<variable>[^=]+)     # get the variable name
(?:=<device\[)         # static '=<device'
(?<index>[^\]]+)       # device number index
(?:]\.)                # static ].
(?<sub>[^>]+)          # Get the sub command
(?:>&?)                # Match but don't capture the > and possible &  
";

 // Ignore pattern whitespace is to document the pattern, does not affect processing.
var items = Regex.Matches(data, pattern, RegexOptions.IgnorePatternWhitespace)
                .OfType<Match>()
                .Select (mt => new
                  {
                     Variable = mt.Groups["variable"].Value,
                     Index    = mt.Groups["index"].Value,
                     Sub      = mt.Groups["sub"].Value
                  })
                 .ToList();

items.ForEach(itm => Console.WriteLine ("{0}:{1}:{2}", itm.Variable, itm.Index, itm.Sub));

/* Output
level:195:level
name:195:name
*/