繁体   English   中英

Java 匹配字符串,直到第一次出现不同的字符串

[英]Java match string until the first occurence of a different string

我正面临 Java 匹配器的其他问题。 我正在尝试使用正则表达式匹配我的 JSON 的内容,而不使用外部库。 我的 JSON 看起来像这样:

[
{
"FIRST":"Tom",
"LAST":"Hanks",
"SUFFIX":""
},
{
"FIRST":"Sammy",
"LAST":"Davis",
"SUFFIX":"Jr."
}
]

但是,我只想匹配前半部分的单词,即第一个},匹配。 我试图创建一个新的模式和匹配器,但我不知道如何进行,以及如何在第一次出现},

Pattern pattern = Pattern.compile("\"([^\"]*)\"");
Matcher matcher = pattern.matcher(loadJSONtoString(fileName).toString());
Pattern pattern2 = Pattern.compile("},");
Matcher matcher2 = pattern2.matcher(loadJSONtoString(fileName).toString());
while(matcher.find())
   {
         myList.add(matcher.group());
         //if matcher2 encounters }. for the first time: break;  
   }

因为您明确表示您不想使用外部库,所以我假设您意识到使用正则表达式解析 JSON 需要很长的路要走,您应该真正使用 JSON 解析库。

除此之外,考虑一下 JSON 解析库本身是如何工作的。 它实际上确实使用了正则表达式。 但不是一个正则表达式,而是有许多正则表达式,每一个都旨在识别 JSON 语法的某些元素:带引号的字符串、数字、左大括号或右大括号等。解析器根据这些定义 JSON 语法正则表达式和由它们构建的东西:“字段”是带引号的字符串,后跟冒号,后跟值,“值”是带引号的字符串或数字或数组或 object,“对象”是打开的大括号后跟零个或多个字段,后跟右大括号等。

使用正则表达式编写非常简单的解析器的一个好方法是定义一个返回“令牌”的正则表达式。 您将每个标记定义为一个捕获组并用“|”分隔它们所以正则表达式可以匹配其中任何一个。 您可以通过检查哪个捕获组匹配来确定它找到了哪个令牌。 (只有其中一个会匹配。)然后重复使用正则表达式返回令牌,直到你得到你想要的。

这是一个可能对您有用的简单正则表达式:

Pattern pattern = Pattern.compile("\"([^\\\"]*)\"|({)|(})|(\\[)|(\\])|(:)|,");

比赛组是:

  1. 带引号的字符串
  2. 开放式支架
  3. 一个紧密的大括号
  4. 开方括号
  5. 一个右方括号
  6. 一个冒号

请注意,逗号没有捕获组,因为它是一种噪音,我们并不真正关心它,并且与引用字符串匹配的正则表达式部分不包括引号本身,因此您不必在解析期间删除引号。

您需要构建一个 function 将此正则表达式应用于字符串的 rest(即,您尚未解析的任何内容),然后遍历匹配组并返回匹配组的编号及其内容。 对于某些匹配,内容不会那么有趣(如果匹配冒号,内容将始终是冒号),但对于带引号的字符串,内容将是字符串本身。

假设有一个名为JsonScanner的 class 有两种方法:

  • getNextToken应用正则表达式并返回令牌的编号(即匹配组的编号)。
  • getContent返回上次匹配的内容。

现在你可以重复调用这些:

JsonScanner scanner(text);
scanner.getNextToken(); // should return '[' token
scanner.getNextToken(); // should return '{' token
scanner.getNextToken(); // should return quoted string
scanner.getContent(); // will return "FIRST"
etc.

您实际上应该检查返回值是否符合您的预期,如果不是,则抛出错误。

一旦您阅读了第一个 object(scanner.getNextToken scanner.getNextToken()返回“}”令牌),您可以停止扫描。

请注意,这是一个非常简单的实现。 例如,带引号的字符串正则表达式不处理字符串中的转义字符。 如果您想实际验证 JSON,您还必须返回逗号令牌并确保正确使用了逗号。 但这是一般的想法。 我自己使用这种确切的策略编写了简单的解析器。

J2EE 实际上包含一个名为JsonParser的 class ,它基本上为您实现了这个策略。 它包含一个next方法,该方法返回一个标识令牌和内容的Event

这是使用类似方法的人,除了不是使用带有一堆捕获组的单个正则表达式,该人使用一堆单独的正则表达式并依次应用每个正则表达式直到匹配。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM