【发布时间】:2020-10-02 01:19:20
【问题描述】:
我在使用正则表达式拆分属性字符串的过程中看到了这个有趣的事情。我无法找到根本原因。
我有一个字符串,其中包含属性键=值对等文本。 我有一个正则表达式,它根据 = 位置将字符串拆分为键/值。它将第一个 = 视为分割点。值也可以包含 =。
我尝试在 Java 中使用两种不同的方式来实现它。
-
使用Scanner.findAll()方法
这与预期不符。它应该根据模式提取和打印所有键。但我发现它的行为很奇怪。我有一个键值对如下
SectionError.ErrorMessage=errorlevel=Warning {HelpMessage:This is very important message This is very important .....}
应该提取的键是 SectionError.ErrorMessage= 但它也将 errorlevel= 视为键。
有趣的一点是,如果我从 String 传递的属性中删除一个字符,它会表现良好并且只提取 SectionError.ErrorMessage= 键。
-
使用 Matcher.results() 方法
这很好用。我们在属性字符串中放什么都没问题。
我尝试过的示例代码:
import java.util.Scanner;
import java.util.regex.MatchResult;
import java.util.regex.Pattern;
import static java.util.regex.Pattern.MULTILINE;
public class MessageSplitTest {
static final Pattern pattern = Pattern.compile("^[a-zA-Z0-9._]+=", MULTILINE);
public static void main(String[] args) {
final String properties =
"SectionOne.KeyOne=first value\n" + // removing one char from here would make the scanner method print expected keys
"SectionOne.KeyTwo=second value\n" +
"SectionTwo.UUIDOne=379d827d-cf54-4a41-a3f7-1ca71568a0fa\n" +
"SectionTwo.UUIDTwo=384eef1f-b579-4913-a40c-2ba22c96edf0\n" +
"SectionTwo.UUIDThree=c10f1bb7-d984-422f-81ef-254023e32e5c\n" +
"SectionTwo.KeyFive=hello-world-sample\n" +
"SectionThree.KeyOne=first value\n" +
"SectionThree.KeyTwo=second value additional text just to increase the length of the text in this value still not enough adding more strings here n there\n" +
"SectionError.ErrorMessage=errorlevel=Warning {HelpMessage:This is very important message This is very important message This is very important messageThis is very important message This is very important message This is very important message This is very important message This is very important message This is very important message This is very important message This is very important messageThis is very important message This is very important message This is very important message This is very important message This is very important message}\n" +
"SectionFour.KeyOne=sixth value\n" +
"SectionLast.KeyOne=Country";
printKeyValuesFromPropertiesUsingScanner(properties);
System.out.println();
printKeyValuesFromPropertiesUsingMatcher(properties);
}
private static void printKeyValuesFromPropertiesUsingScanner(String properties) {
System.out.println("===Using Scanner===");
try (Scanner scanner = new Scanner(properties)) {
scanner
.findAll(pattern)
.map(MatchResult::group)
.forEach(System.out::println);
}
}
private static void printKeyValuesFromPropertiesUsingMatcher(String properties) {
System.out.println("===Using Matcher===");
pattern.matcher(properties).results()
.map(MatchResult::group)
.forEach(System.out::println);
}
}
打印输出:
===Using Scanner===
SectionOne.KeyOne=
SectionOne.KeyTwo=
SectionTwo.UUIDOne=
SectionTwo.UUIDTwo=
SectionTwo.UUIDThree=
SectionTwo.KeyFive=
SectionThree.KeyOne=
SectionThree.KeyTwo=
SectionError.ErrorMessage=
errorlevel=
SectionFour.KeyOne=
SectionLast.KeyOne=
===Using Matcher===
SectionOne.KeyOne=
SectionOne.KeyTwo=
SectionTwo.UUIDOne=
SectionTwo.UUIDTwo=
SectionTwo.UUIDThree=
SectionTwo.KeyFive=
SectionThree.KeyOne=
SectionThree.KeyTwo=
SectionError.ErrorMessage=
SectionFour.KeyOne=
SectionLast.KeyOne=
这可能是什么根本原因?扫描仪的 findAll 与 matcher 的工作方式是否不同?
如果需要更多信息,请告诉我。
【问题讨论】:
-
@Sweeper 我已经更新了标签。由于拼写错误,它被添加了。感谢您的关注。
标签: java regex pattern-matching java.util.scanner java-9