使用Java和正则表达式,我想从一行文本中提取字符串。文本可以是以下格式-
- key1 (value1) key2 (value2)
- key1 (value1) key2
- key1 key2 (value2)
- key1 key2
- key1
当使用类型#1时,我成功地提取了键和值,我可以使用空格分割文本,然后使用以下模式提取键
Pattern p = Pattern.compile("\((.*?)\)",Pattern.DOTALL);
一个复杂的代码逻辑,用于计算"("的出现次数并将其与的出现次数进行匹配空格可以用于Case #2和Case #3,但是,代码变得太长了。当值中也存在空格时,会出现多重复杂性,因为这样拆分文本就会出现问题。
是否有更好的正则表达式拆分/假期我可以使用上面描述的选择性情况?
考虑以下通用正则表达式的powershell示例。
(?<=^|[s)n])[n]*([^(ns]*)([(]([^)n]*)[)])?
$Matches = @()
$String = 'key1(value1) key2(value2)
key3(value3) key3.5
key4 key5(value5) GoofyStuff(I like kittens)
key6 key7 ForReal-Things(be sure to vote)
key8'
Write-Host start with
write-host $String
Write-Host
Write-Host found
([regex]'(?<=^|[s)n])([^(ns]*)([(]([^)n]*)[)])?').matches($String) | foreach {
if ($_.Groups[1].Value) {
write-host "key at $($_.Groups[1].Index) = '$($_.Groups[1].Value)'"
if ($_.Groups[3].Value) {
write-host "value at $($_.Groups[3].Index) = '$($_.Groups[3].Value)'"
} # end if
} # end if
} # next match
<标题>收益率h1> 总结-
(?<=^|[s)n]*)
查找键的开头,每个键都假定在字符串的开头,或者在n, "("或空格-(?<=^|[s)n]*)
之后。这可能在Java中不起作用,因为Java如何处理未定义大小的查找有一个bug/特性。(另见) (?<=^|[s)n])
查找键的开头,假设每个键位于字符串的开头,或在n, "("或空格-(?<=^|[s)n])
之后。在c#和Powershell中([^(ns]*)
返回直到下一个"(",n或s的所有字符([(]([^)n]*)[)])?
返回参数中存在的值循环中的额外逻辑测试Matches数组以验证是否找到了键名或值。在powershell中,$Matches会自动填充字符串中的所有匹配项。
我的建议是:
Pattern p = Pattern.compile("(\(?[^ \n(]+\)?)+"), Pattern.DOTALL);
然后,遍历子匹配项。如果第一个字符是父字符,你知道它是前一个键的值;否则,它就是一个键。如果它是一个值,只需使用substring
将父元素去掉。