如果使用正则表达式将空格用作分隔符,如何处理值中的空格?

时间:2019-07-17 16:18:02

标签: java regex

我正在尝试运行正则表达式以捕获以下字符串的键和值:

name="Evoke Sprite" parent="EvokeObjects" instance=ExtResource( 5 ) id=5

以下是每个语法注意事项:

  • 键:一串字母,没有空格
  • 值:

    • 可能带有引号,例如。 “ EvokeObjects”
    • 引号内可能有空格
    • 在引号中可能包含特殊字符,例如“ hello / world @!18”
    • 可能具有类似于字符串的功能(“ ExtResource(5)”)。
    • 函数字符串在方括号内将有空格

我已经尽可能在引号中使用空格:

(.*?)=(?:"(.*?)"|(.*?))(?: |$)

所以这将与 name="Evoke Sprite" parent="EvokeObjects" id=5

regex101进行测试:https://regex101.com/r/xkRRsD/1

当我添加ExtResource( 5 )时会出现问题,因为它在方括号内有空格。然后以前的正则表达式代码将失败。

作为一种可能的解决方法,我想也许可以通过在代码中执行字符串替换来完全删除括号中的空格。但是我想知道是否有正则表达式解决方案?

3 个答案:

答案 0 :(得分:2)

在替换的第二部分中,您将进行匹配,直到字符串的空格或结尾,以匹配ExtResource(

您可以做的是不匹配括号,或者匹配从开头到结尾的括号。

您可以使用negated character class来代替非贪婪的量词。

([^=\s]+)=(?:"([^"]+)"|((?:[^\s()"]|\([^()]*\))+))

说明

  • ([^=]+)=捕获组1,匹配除=之外的任何字符,然后匹配=
  • (?:非捕获组
    • "([^"]*)"匹配“,然后捕获组2中除“之外的所有字符”,然后匹配“
    • |
    • (捕获组3
      • (?:非捕获组
        • [^\s()"]匹配除()"或空白字符之外的所有字符
        • |
        • \([^()]*\)从开括号到右括号的匹配
      • )+关闭非捕获组并重复1次以上
    • )关闭第3组
  • )关闭非捕获组

Regex demo

答案 1 :(得分:1)

编辑:v5,这应该会影响所有@Andreas的测试用例。

看起来您的正则表达式非常接近,但是您的非捕获组中的最后一条语句(.*?)会将开放括号后的空格视为其搜索的“结尾”,因为它占用了空格前应尽可能少的字符。既然您知道函数字符串在括号之间会有空格,那么此正则表达式似乎可以解决问题:

(\S*?)=(?:"(.*?)"|(\S*?\(.*?\))|(\S*?))(?: |$)

至关重要的是,\S可以匹配任何非空格字符-由于永远不会出现像id=some val这样的示例,因此这是一个很好的选择,因为它不会在括号中出现功能。它还可以确保键名没有空格,例如pare nt=val

Try it here!

答案 2 :(得分:0)

您可以使用

([a-z]+)=(?:"(.*?)"|(.*?))(?:(?=[a-z]+?=)|$)

enter image description here

Regex Demo