【问题标题】:Regex extract list of strings between two strings正则表达式提取两个字符串之间的字符串列表
【发布时间】:2014-06-12 10:25:40
【问题描述】:

我有一个字符串,我想从中提取包含在两个字符串之间的字符串列表:['']。我尝试了几个我在网上找到的正则表达式规则(特别是this question),但问题在于正确转义字符以使正则表达式工作。

如何提取两个字符串之间的字符串列表?我想做这样的事情:

List<string> TheListOfStrings = Regex.Matches(TheText, "....");

源是一个 JavaScript 块,我想从中提取对象键:例如,TheObject['SomeProp'] = TheOtherObject['OtherProp'],因此列表应包含SomePropOtherProp;键可以在输入文本中出现多次。

【问题讨论】:

  • 你能举个例子吗?
  • 那么,源代码看起来像 ['a, b, c'] 或 ['a'], ['b'], ['c'] 还是什么?你能给我们看看吗?
  • 另外,一个字符串是否可以包含多个匹配项,例如"a['bc']d['ef']gh']"
  • @ClickRick:是的,这可能会发生;同样,重要的是 [' 和 '] 之间的内容,所以在你的情况下,它应该返回 bc 和 ef

标签: c# regex


【解决方案1】:

使用一般模式

(?<=prefix)find(?=suffix)

它使用lookbehind和lookahead来查找模式而不将它们包含在结果中。

在哪里
前缀\[';左括号被转义。
找到     是.*?;任何字符的序列,但尽可能少。
后缀']

(?<=\[').*?(?='])
List<string> TheListOfStrings = Regex.Matches(input, @"(?<=\[').*?(?='])")
    .Cast<Match>()
    .Select(m => m.Value)
    .ToList();

如果您重复调用同一个正则表达式,请为其创建一个可重复使用的实例,而不是调用静态方法。此外,如果您多次使用它,请考虑使用Compiled 选项。它会跑得更快;但是,代价是初始化时间更长。

var regex = new Regex(@"(?<=\[').*?(?='])", RegexOptions.Compiled);

while (loop_condition) {

    List<string> TheListOfStrings = regex.Matches(input)
        .Cast<Match>()
        .Select(m => m.Value)
        .ToList();
    ...

}

【讨论】:

  • 在上下文中显示该模式,提取输入字符串的所需部分并生成所需的输出字符串,使用问题下的 cmets 中的测试数据。
  • 我添加了一个代码示例。该示例经过测试并产生所需的输出。
  • 我试过了:它可以工作并且代码更干净。然后,我放了一个秒表并计时。此代码运行时间为 217 毫秒,而其他代码运行时间为 10 毫秒。我认为这与正则表达式的编译有关,所以在下面的调用中,结果是 213 毫秒对 9 毫秒。不知道为什么会有这样的差异,但这就是我所看到的。
  • 我添加了一个例子,如果你多次调用它会更快。
【解决方案2】:

only 的主要困难在于使方括号被识别为分隔文本而不是正则表达式的一部分。

string input = "a['bc']d['ef']gh']";
MatchCollection matches = Regex.Matches(input, @"\['(?<key>.*?)'\]");
var listOfKeys = matches.Cast<Match>().Select(x => x.Groups["key"].Value);

成功了。

如果性能很重要并且要运行多次,那么编译正则表达式将会看到明显的胜利:

string input = "a['bc']d['ef']gh']";
Regex re = new Regex(@"\['(?<key>.*?)'\]", RegexOptions.Compiled);
MatchCollection matches = re.Matches(input);
var listOfKeys = matches.Cast<Match>().Select(x => x.Groups["key"].Value);

【讨论】:

  • 现在试试 我已经调试好了正确
  • 所以好消息是它有效。问题是我之前的实现(手动循环输入字符串)返回了 3331 个项目,而您拥有的正则表达式正在返回 3330 个项目。我需要看看为什么,但总的来说,正则表达式花费了不到一秒的时间,而我的手动实现目前需要 10 多秒。
  • 您是否特别希望它在处理大量输入数据时执行得更快?
  • 好的,一切正常。当然,越快越好;这是不涉及用户的后台任务的一部分,因此性能不是必需的,但有任何帮助!你有什么建议?
  • 好的,所以代码从大约 30 毫秒到大约 20 毫秒,所以它确实在编译选项打开后得到了改进。请注意,前面的代码运行大约需要 12-15 秒...感谢您的帮助!!!
【解决方案3】:

这可能满足您的需求:(?&lt;=\[")[^"]+(?="\])|(?&lt;=\[')[^']+(?='\])

对于a['bc']d['ef']gh'],这将返回bcef

【讨论】:

  • 我试过这个: var Test = Regex.Matches(TheText, "(?
  • 试试这个:字符串模式 = "(?
  • 仍有“无法识别的转义序列”下划线。
  • @frenchie 可能就像字符串前缺少@ 符号一样简单。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-30
  • 1970-01-01
  • 1970-01-01
  • 2017-04-15
  • 1970-01-01
  • 2014-12-08
相关资源
最近更新 更多