2

我正在解析一个要提取某个字符串的文件。

字符串前面会出现一些空格,然后是:

  • 一个 H 后跟 8 个十六进制数字

或者

  • 一个 G 后跟 9 个十六进制数字

后跟回车和换行符。

我是否可以做出一个相当于“如果字符是 H,则跳过 8 个字符,否则如果字符是 G,则跳过 9 个字符”或更简单的“如果字符是 H,则跳过”的表达式8 个字符,否则跳过 9 个字符”。

我目前与 H 配合良好的正则表达式是@"\s+H.{8}(? <user>.*)\r\n",但在添加条件字符数时我很难过。例如,如果有像 [H|G].{8|9} 这样的语法,那就太好了,但我认为这实际上并不存在于正则表达式语法中。

4

4 回答 4

4

根据我的评论,我只是详细说明了你的

\s+((H.{8})|(G.{9}))(?<user>.*)\r\n

正则表达式可视化

调试演示

由于正则表达式对应于有限状态自动机,因此很容易看出为什么这是微不足道的,在读取 H 时我们进入一种状态,G 进入另一种状态。

于 2013-10-28T20:15:37.913 回答
2

我会使用:

\s+(?:H[a-fA-F0-9]{8}|G[a-fA-F0-9]{9})(?<user>.*)\r\n
于 2013-10-28T19:07:37.483 回答
1

那么它是可能的Regex。您可以在正则表达式中使用条件。

这是您正在努力解决的“正则表达式”的主要部分。我假设你可以用这个来构建。

var subject = "H12345678ABC";
var regex = new Regex(@"(?((?<hgroup>H))\k<hgroup>.{8}|.{10})(?<user>.*)");
var match =regex.Match(subject);
if(match.Success)
{
    Console.WriteLine(match.Groups["user"].Value);//prints ABC
}
else
{
    Console.WriteLine("No Match");
}

分手:

(?<hgroup>H)    Matches H and stores in group hgroup
\k<hgroup>.{8}  If true checks matches H followed by any 8 characters
.{10}           If not then match next 10 characters(G followed by 9 other characters)
(?<user>.*)     Captures rest all to user group

这是一个工作演示

于 2013-10-28T19:23:00.973 回答
0

这有两个 if 条件。使用正则表达式选项 IgnorePatternWhitespace 允许评论

(?(H0[xX][0-9a-fA-F]{6}[^\r\n\d]+)     # If an H with 8 hex digits is found
     H.{8}(?<User>[^\r\n\d]+)          # Then match the H user
    |                                  # else
    (?(G0[xX][0-9a-fA-F]{7}[^\r\n\d]+) # If G with 9 hex is found
      G.{9}(?<User>[^\r\n\d]+))        # Then match the G User
 )

更新

阿喀琉斯的治疗方法是不清楚用户名由什么组成......如果用户名有一个数字说1OmegaMan......这将失败。但是OP没有指定该规则,也没有给出任何明确的例子。

所以这里的假设是用户名都是字母字符。

一种更好的搜索模式可能H\d{8}[A-Z][^\r\n]+是表示在从数字中描述用户名的数字之后至少存在一个字母字符。

于 2013-10-28T19:35:04.520 回答