正则表达式只在字符串后匹配重复模式

时间:2014-02-26 19:54:13

标签: java regex

PropDefinition 成为prop\d+ (true|false)

形式的字符串

我有一个字符串:

((prop5 true))

sat
((prop0 false)
 (prop1 false)
 (prop2 true))

我想在文本'sat'之后提取底部的 PropDefinitions ,所以匹配应该是:

prop0 false
prop1 false
prop2 true

我最初尝试使用/(prop\d (?:true|false))/ssee example here),但这显然与所有 PropDefinitions 匹配,并且我无法在sat字符串之后使其匹配重复

我上面使用rubular作为例子,因为它很方便,但我真的在寻找最与语言无关的解决方案。如果它是至关重要的信息,我很可能会在Java应用程序中使用正则表达式。

6 个答案:

答案 0 :(得分:0)

str =<<-Q
((prop5 true))

sat
((prop0 false)
 (prop1 false)
 (prop2 true))
Q

p str[/^sat(.*)/m, 1].scan(/prop\d+ (?:true|false)/)

# => ["prop0 false", "prop1 false", "prop2 true"]

答案 1 :(得分:0)

如果您的模式在本质上非常不同(sat之后的字符串并选择特定模式),通常最好在多个正则表达式中表达它们而不是尝试使用单一的正则表达式。

s = <<_
((prop5 true))

sat
((prop0 false)
 (prop1 false)
 (prop2 true))
_

s.split(/^sat\s+/, 2).last.scan(/prop\d+ (?:true|false)/)
# => ["prop0 false", "prop1 false", "prop2 true"]

答案 2 :(得分:0)

部分混淆与SingleLine与MultiLine匹配有关。下面的模式适用于我,并在一次执行中返回所有匹配,无需初步操作来拆分字符串。

这个需要单独指定SingleLine模式(如在.Net RegExOptions中):

(?<=sat.*)(prop\d (?:true|false))

这个指定SingleLine模式内联,它适用于许多但不是所有的RegEx引擎:

(?s)(?<=sat.*)(?-s)(prop\d (?:true|false))

你没有需要通过(?-s)关闭SingleLine模式,但我认为它的意图更清晰。

以下模式也会内联切换SingleLine模式,但使用Negative LookAhead而不是Positive LookBehind(根据regular-expressions.info [确保从下拉列表中选择Ruby和Java])Ruby引擎不支持LookBehinds - 正面或负面 - 取决于版本,甚至不允许量词(在下面的评论中也注明@revo)。这种模式应该适用于Java,.Net,很可能是Ruby,以及其他模式:

(prop\d (?:true|false))(?s)(?!.*sat)(?-s)

答案 3 :(得分:0)

\s+[(]+\K(prop\d (?:true|false)(?=[)]))

Live demo

答案 4 :(得分:0)

如果Ruby可以支持\G锚,这是一个解决方案 它看起来很讨厌,但有几件事情正在发生 1.它只允许一个巢(外部加多个内部)
2.它不符合不符合'(prop\d true|false)'

的无效表单

如果没有条件2,那么两个正则表达式的指标将会更容易 解决方案也会这样做。首先捕获外部表单sat((..)..(..)..) 第二个是全局捕获内部形式(prop\d true|false)

可以在一个正则表达式中完成,虽然这很难看,但应该可以工作(Perl下面的测试用例)。

# (?:(?!\A|sat\s*\()\G|sat\s*\()[^()]*(?:\((?!prop\d[ ](?:true|false)\))[^()]*\)[^()]*)*\((prop\d[ ](?:true|false))\)(?=(?:[^()]*\([^()]*\))*[^()]*\))

 (?:
      (?! \A | sat \s* \( )
      \G                            # Start match from end of last match
   |                              # or,
      sat \s* \(                    # Start form 'sat ('
 )
 [^()]*                        # This check section consumes invalid inner '(..)' forms
 (?:                           # since we are looking specifically for '(prop\d true|false)'
      \( 
      (?!
           prop \d [ ] 
           (?: true | false )
           \)
      )
      [^()]* 
      \)
      [^()]* 
 )*                            # End section, do optionally many times
 \( 
 (                             # (1 start), match inner form '(prop\d true|false)'
      prop \d [ ] 
      (?: true | false )
 )                             # (1 end)
 \)
 (?=                           # Look ahead for end form  '(..)(..))'
      (?:
           [^()]* 
           \( [^()]* \)
      )*
      [^()]* 
      \) 
 )

Perl测试用例

$/ = undef;

$str = <DATA>;

while ($str =~ /(?:(?!\A|sat\s*\()\G|sat\s*\()[^()]*(?:\((?!prop\d[ ](?:true|false)\))[^()]*\)[^()]*)*\((prop\d[ ](?:true|false))\)(?=(?:[^()]*\([^()]*\))*[^()]*\))/g)
{
   print "'$1'\n";
}

__DATA__
((prop10 true))
sat
((prop3 false)
(asdg) 

(propa false)

 (prop1 false)
 (prop2 true)
)
((prop5 true))

输出&gt;&gt;

'prop3 false'
'prop1 false'
'prop2 true'

答案 5 :(得分:-2)

/(?<=sat).*?(prop\d (true|false))/m

匹配组1 是您想要的。请参阅example

但是,我真的建议先拆分字符串。这更容易。

相关问题