这可能非常简单,但是我对regex还是陌生的,有一个要求,我需要在字符串中进行一些regex匹配并提取其中的数字。以下是我的代码,其中包含示例i / p和必需的o / p。我尝试通过引用https://www.freeformatter.com/java-regex-tester.html来构造Pattern
,但是我的正则表达式匹配项本身返回false。
Pattern pattern = Pattern.compile(".*/(a-b|c-d|e-f)/([0-9])+(#[0-9]?)");
String str = "foo/bar/Samsung-Galaxy/a-b/1"; // need to extract 1.
String str1 = "foo/bar/Samsung-Galaxy/c-d/1#P2";// need to extract 2.
String str2 = "foo.com/Samsung-Galaxy/9090/c-d/69"; // need to extract 69
System.out.println("result " + pattern.matcher(str).matches());
System.out.println("result " + pattern.matcher(str1).matches());
System.out.println("result " + pattern.matcher(str1).matches());
所有上述SOP都返回false。我正在使用Java 8,是否可以通过一种方法在单个语句中匹配模式,然后从字符串中提取 digit 。
如果有人可以指出如何调试/开发正则表达式,我将非常高兴。如果我的问题中有不清楚的地方,请随时告诉我。
答案 0 :(得分:2)
您可以使用
Pattern pattern = Pattern.compile(".*/(?:a-b|c-d|e-f)/[^/]*?([0-9]+)");
请参见regex demo
与matches()
一起使用时,上面的模式不需要显式锚点^
和$
。
详细信息
.*
-除换行符以外的任意0+个字符,并且尽可能多/
-最右边的/
,后跟子模式(?:a-b|c-d|e-f)
-与以下任何备选方案相匹配的非捕获组:a-b
,c-d
或e-f
/
-一个/
字符[^/]*?
-除/
之外的任何字符,请尽可能少([0-9]+)
-第1组:一个或多个数字。List<String> strs = Arrays.asList("foo/bar/Samsung-Galaxy/a-b/1","foo/bar/Samsung-Galaxy/c-d/1#P2","foo.com/Samsung-Galaxy/9090/c-d/69");
Pattern pattern = Pattern.compile(".*/(?:a-b|c-d|e-f)/[^/]*?([0-9]+)");
for (String s : strs) {
Matcher m = pattern.matcher(s);
if (m.matches()) {
System.out.println(s + ": \"" + m.group(1) + "\"");
}
}
使用相同正则表达式并添加锚的替换方法:
List<String> strs = Arrays.asList("foo/bar/Samsung-Galaxy/a-b/1","foo/bar/Samsung-Galaxy/c-d/1#P2","foo.com/Samsung-Galaxy/9090/c-d/69");
String pattern = "^.*/(?:a-b|c-d|e-f)/[^/]*?([0-9]+)$";
for (String s : strs) {
System.out.println(s + ": \"" + s.replaceFirst(pattern, "$1") + "\"");
}
输出:
foo/bar/Samsung-Galaxy/a-b/1: "1"
foo/bar/Samsung-Galaxy/c-d/1#P2: "2"
foo.com/Samsung-Galaxy/9090/c-d/69: "69"
答案 1 :(得分:2)
因为您总是匹配正则表达式中的最后一个数字,所以我想只将struct
与此正则表达式newDF.select($"parsed.propertyNameInTheParsedJsonObject")
一起使用:
replaceAll
如果结果为空,则您没有任何数字。
输出
.*?(\d+)$
答案 2 :(得分:2)
这是使用String#replaceAll
的单线纸:
public String getDigits(String input) {
String number = input.replaceAll(".*/(?:a-b|c-d|e-f)/[^/]*?(\\d+)$", "$1");
return number.matches("\\d+") ? number : "no match";
}
System.out.println(getDigits("foo.com/Samsung-Galaxy/9090/c-d/69"));
System.out.println(getDigits("foo/bar/Samsung-Galaxy/a-b/some other text/1"));
System.out.println(getDigits("foo/bar/Samsung-Galaxy/9090/a-b/69ace"));
69
no match
no match
这适用于您提供的样本输入。请注意,我添加了逻辑,在无法匹配结尾数字以适合您的模式的情况下,它将显示no match
。在不匹配的情况下,通常会留下原始的输入字符串,而不是全数字。