Java 如果将空格用作正则表达式的分隔符,如何处理值中的空格?
我正在尝试运行正则表达式以捕获以下字符串的键和值:Java 如果将空格用作正则表达式的分隔符,如何处理值中的空格?,java,regex,Java,Regex,我正在尝试运行正则表达式以捕获以下字符串的键和值: name=“Evoke Sprite”parent=“EvokeObjects”实例=外部资源(5)id=5 下面是每种语言的一些语法注释,如下所示: 键:一串字母,没有空格 价值观: 可能有引号,例如“EvokeObjects” 引号内可能有空格 引号内可能有特殊字符,例如“hello/world@!18” 可能具有类似字符串(“ExtResource(5)”的函数 函数字符串在括号内有空格 我已经在引号中找到了空格: (.*)=(?
name=“Evoke Sprite”parent=“EvokeObjects”实例=外部资源(5)id=5
下面是每种语言的一些语法注释,如下所示:
- 键:一串字母,没有空格
- 价值观:
- 可能有引号,例如“EvokeObjects”
- 引号内可能有空格
- 引号内可能有特殊字符,例如“hello/world@!18”
- 可能具有类似字符串(“ExtResource(5)”的函数
- 函数字符串在括号内有空格
(.*)=(?:“(.*)”|(.*)(?:|$)
因此,这将与
name=“唤醒精灵”parent=“唤醒对象”id=5
要测试的regex101:
当我添加外部资源(5)
时会出现问题,因为它在括号内有空格。然后,前面的正则表达式代码失败
作为一种可能的解决方法,我想也许我可以通过在代码中进行字符串替换,将括号中的空格全部删除。但是我想知道是否有一个正则表达式来解决这个问题?在替换的第二部分中,您将匹配到一个空格或字符串的末尾,以便匹配
外部资源(
您可以做的是不匹配括号或从开始匹配到结束括号
您可以使用一个非贪婪的量词,而不是使用非贪婪的量词
解释
捕获组1,匹配除([^=]+)=
之外的任何字符,然后匹配=
=
非捕获组(?:
Match”,然后捕获除“在组2中,然后匹配”之外的任何字符“([^”]*)”
或|
捕获组3(
非捕获组(?:
匹配除[^\s()”]
,(
,)
或空白字符以外的任何字符“
或|
从开始到结束的括号匹配\([^()]*\)
关闭非捕获组并重复1+次)+
关闭第3组)
关闭非捕获组)
([a-z]+)=(?:"(.*?)"|(.*?))(?:(?=[a-z]+?=)|$)
编辑:v5,这应该会影响@Andreas的所有测试用例 看起来您的正则表达式非常接近,但非捕获组中的最后一条语句,
(.*)
,将把开括号后的空格视为“结束”它的搜索,因为它在到达空格之前消耗尽可能少的字符。假设您知道函数字符串在括号之间有空格,这个正则表达式似乎可以做到:
(\S*?)=(?:“(.*?”)(\S*?\(.*?\)(\S*?)(?:$)
关键的是,\S
匹配任何非空白字符-因为永远不会有像id=some val
这样的示例,这是一个很好的选择,因为它不会在函数中的括号上运行。它还确保键名没有空格,比如pare nt=val
“一个文本字符串,没有空格”你是指一个字符字符串还是一个字母字符串?不管怎样。
*?
不是,因为它包括空格。如果输入是。$%^=*@(!)
这是一个有效的键。$%^
/value*@(!)
组合吗?你能将带有空格的字符串作为值而没有"
i.ekey=some value some random value
@CodeManiac在这种情况下,如果它需要空格,它会有引号,所以我不必担心这种情况。@Andreas它很可能只有字母。不会有任何特殊字符,也不会有任何数字。对于值,带引号的字符串可以有特殊字符字符如“hello/world@!”
@Andreas你说得对,谢谢。我已经更新了它。@Andreas现在它也将匹配这些字符。不确定a=
是否应该匹配为带有空值的键a
。要求中没有任何内容排除它。你的正则表达式将不匹配。但是,无论如何,将我的反对票改为赞成票。谢谢(并为您提供反馈)。让我们等待OP来澄清这一部分,我会相应地更新它。这很好,我想我可能需要做一些查找,但这是一个更简单的解决方案。我承认,我对否定字符类有点不熟悉,但你的清晰解释对我帮助很大。与name=Evoke Sprite parent=Evoke objects根据规则。规则规定值中的空格只能在引用或括号内出现。@Andreas OP确认没有空格,无论如何感谢你的反馈我不知道是否允许我在评论中问这个问题,但我喜欢你那里的图形。你是如何生成的?@Flare这就是开源的魅力所在除了分享知识,这是使用好的捕获生成的。我会研究一下,看看我能找到什么。@Andreas看起来像是我找到了你提到的案例-请参阅更新。它是否匹配错误输入?例如a=b(5)c)
或a=“b”c
?我会说不。或者至少只匹配有效部分b(5)
和“b”
。但是,可以进行解释,所以删除否决票。
([a-z]+)=(?:"(.*?)"|(.*?))(?:(?=[a-z]+?=)|$)