0

我要验证的文本字符串由我所谓的“段”组成。单个段可能如下所示:

 [A-Z,S,3]

到目前为止,我设法构建了这个正则表达式模式

(?:\[(?<segment>[^,\]\[}' ]+?,[S|D],\d{1})\])+?

它可以工作,但即使整个文本字符串包含无效文本,它也会返回匹配项。我想我需要在我的模式中的某个地方使用^$,但我不知道怎么做!?

我希望我的模式产生以下结果:

  • [A-Z,S,3][A-Za-z0-9åäöÅÄÖ,D,4] OK(两段)
  • [A-Z,S,3]aaaa[A-Za-z0-9åäöÅÄÖ,D,4] 没有匹配
  • crap[A-Z,S,3][A-Za-z0-9åäöÅÄÖ,D,4] 没有匹配
  • [A-Z,S,3][] 没有匹配
  • [A-Z,S,3][klm,D,4][0-9,S,1] OK(三段)
4

2 回答 2

3

使用 ^ 锚定开始,使用 $ 锚定结束。例如: ^(abc)*$,这匹配组的零个或多个重复(在本例中为“abc”),并且必须从输入字符串的开头开始并在其末尾结束。

^(?:[(?[^,][}' ]+?,[S|D],\d{1})])+$——使用不贪心的+?并不重要,因为无论如何你都要求它匹配到最后。但是,您的正则表达式有一些问题。

^(?:\[[^,]+,[SD],\d\])+$——看起来更像你想要的。

  • 我无法解读第一部分的意思,所以我的正则表达式比要求的更通用,[^,]+,将匹配任何非逗号后跟逗号的序列,实际上你可能应该添加]到这个否定字符类。
  • [S|D]三个字符的字符类,|在这里并不意味着交替((S|D)虽然意思相同[SD])。
  • {1}是任何原子的默认值,您无需指定它。

伪代码(在codepad.org运行):

import re
def find_segments(input_string):
  results = []
  regex = re.compile(r"\[([^],]+),([SD]),(\d)\]")
  start = 0
  while True:
    m = regex.match(input_string, start)
    if not m: # no match
      return None # whole string didn't match, do another action as appropriate
    results.append(m.group(1, 2, 3))
    start = m.end(0)
    if start == len(input_string):
      break
  return results

print find_segments("[A-Z,S,3][klm,D,4][0-9,S,1]")
# output:
#[('A-Z', 'S', '3'), ('klm', 'D', '4'), ('0-9', 'S', '1')]

这里最大的区别是表达式只匹配完整的[...]部分,但它是连续应用的,所以它们必须从最后一个结束的地方重新开始(或在字符串的末尾结束)。

于 2010-01-01T09:21:29.827 回答
0

你想要这样的东西:

/^(\[[^],]+,[SD],\d\])+$/

以下是如何在 C# 中使用此正则表达式的示例:

using System;
using System.Text.RegularExpressions;

class Program
{
    static void Main(string[] args)
    {
        string[] tests = {
            "[A-Z,S,3][A-Za-z0-9,D,4]",
            "[A-Z,S,3]aaaa[A-Za-z0-9,D,4]",
            "crap[A-Z,S,3][A-Za-z0-9,D,4]",
            "[A-Z,S,3][]",
            "[A-Z,S,3][klm,D,4][0-9,S,1]"
        };

        string segmentRegex = @"\[([^],]+,[SD],\d)\]";
        string lineRegex = "^(" + segmentRegex + ")+$";

        foreach (string test in tests)
        {
            bool isMatch = Regex.Match(test, lineRegex).Success;
            if (isMatch)
            {
                Console.WriteLine("Successful match: " + test);
                foreach (Match match in Regex.Matches(test, segmentRegex))
                {
                    Console.WriteLine(match.Groups[1]);
                }
            }
        }
    }
}

输出:

Successful match: [A-Z,S,3][A-Za-z0-9,D,4]
A-Z,S,3
A-Za-z0-9,D,4
Successful match: [A-Z,S,3][klm,D,4][0-9,S,1]
A-Z,S,3
klm,D,4
0-9,S,1
于 2010-01-01T09:19:22.967 回答