使用Java和正则表达式拆分复杂的字符串



使用Java和正则表达式,我想从一行文本中提取字符串。文本可以是以下格式-

  1. key1 (value1) key2 (value2)
  2. key1 (value1) key2
  3. key1 key2 (value2)
  4. key1 key2
  5. 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将父元素去掉。

最新更新