【问题标题】:Regex - Match quotes between brackets正则表达式 - 匹配括号之间的引号
【发布时间】:2019-09-30 20:11:12
【问题描述】:

示例字符串:

cov('年龄', ['5','7','9'])

我有这个匹配引号内的值的正则表达式:

(["'])(?:(?=(\\?))\2.)*?\1

我正在尝试将其修改为仅使用前瞻/后视从示例字符串返回方括号内的引号:

(?<=\[)(["'])(?:(?=(\\?))\2.)*?\1(?=\])

但它匹配方括号内的所有内容。

如何只匹配第一个正则表达式中没有逗号的引号,但在方括号内?

编辑。

语言是 .NET。

【问题讨论】:

  • 哪种语言或正则表达式引擎?在 PCRE 中,第四只鸟的答案是一个很好的答案,在其他正则表达式中它可能不起作用。
  • 已编辑:语言为 .NET。
  • 你在做什么?删除[....] 内的所有'"?是 C# 吗?您有权访问代码吗?结果可能会简单得多。你有cov('Age', ['5','7','9']),确切的预期结果及其类型是什么?
  • 是的,这是我的代码。 C#。我从 get 请求中收到此字符串,并且必须将括号内的值动态转换为 .Net 数组。

标签: .net regex


【解决方案1】:

如果支持,一个选项是使用 \G 锚点和捕获组:

(?:\[|\G(?!^))('[^']+'),?(?=[^\]]*\])

部分

  • (?:非捕获组
  • \[ 比赛开幕[
    • |或者
    • \G(?!^)在上一场比赛结束时断言位置
  • )关闭非捕获组
  • (捕获组1
    • '[^']+' 匹配',除' 之外的任何字符1 次以上,然后再次匹配'
  • )关闭第一组
  • ,? 匹配一个可选的,
  • (?=[^\]]*\]) 正向前瞻,断言结束 ]

Regex demo | C# demo

例如

string pattern = @"(?:\[|\G(?!^))('[^']+'),?(?=[^\]]*\])";
string input = @"cov('Age', ['5','7','9'])";

var results = Regex.Matches(input, pattern)
.Cast<Match>()
.Select(m => m.Groups[1].Value)
.ToArray();

foreach(string result in results)
{
    Console.WriteLine(result);
}

输出

'5'
'7'
'9'

【讨论】:

  • 完美运行,谢谢!!只有一个问题:有一种方法可以使用反斜杠“\”来转义引号字符?假设我想在数组的一个元素中写一个引号:['5','5\''],这样反斜杠就不会破坏正则表达式。我的示例中的第一个正则表达式执行“(?=(\\?))”,因为我不确定如何将其应用于您的示例。
【解决方案2】:

您尚未指定语言或正则表达式引擎,因此很难回答您的问题。第四只鸟的答案适用于特定的正则表达式引擎(例如 PCRE),但不适用于其他引擎。 .NET 中也存在另一种选择。

对于,您可以使用以下内容,因为此正则表达式引擎将所有捕获收集到CaptureCollection

See regex in use here

\[('[^']*'[,\]])+(?<=])

对于大多数其他语言(此答案或@Thefourthbird's 未涵盖),您需要分两步执行此操作:

  • 获取与\[([^[\]]*)] 匹配的所有字符串(您想要第1 组的值)
  • 匹配所有出现的'([^']*)'(您需要第 1 组的值作为内容)

【讨论】:

    【解决方案3】:

    您似乎不需要任何复杂的正则表达式:在两个方括号之间抓取一个字符串,并用单引号或逗号分隔捕获的内容,或者在那里明确匹配您需要的内容。

    给定

    var text = "cov('Age', ['5','7','9'])";
    

    方法可以是:

    // Split captured text with ' and , 
    var results = Regex.Matches(text, @"\[([^][]+)]")
            .Cast<Match>()
            .Select(x => x.Groups[1].Value.Split('\'', ',').Where(c => !string.IsNullOrEmpty(c)));
    

    或者,匹配括号之间的字符串,然后从中提取所有 1+ 数字块:

    var results1 = Regex.Matches(text, @"\[([^][]+)]")
            .Cast<Match>()
            .Select(x => Regex.Matches(x.Groups[1].Value, @"\d+"));
    

    或者,只提取[...]中的所有数字:

    var results = Regex.Matches(text, @"(?<=\[[^][]*)\d+(?=[^][]*])").Cast<Match>().Select(x => x.Value);
    

    这里,regex matches

    • (?&lt;=\[[^][]*) - 以[ 和除[] 以外的任何数量的字符开头的位置
    • \d+ - 1 位以上
    • (?=[^][]*]) - 位置后跟除 []] 之外的任何 0+ 字符。

    the online C# demo

    它变得有点复杂to extract any number,将\d+ 替换为[-+]?\d*\.?\d+([eE][-+]?\d+)?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-08
      • 1970-01-01
      • 2011-08-03
      相关资源
      最近更新 更多