正则表达式:如果在模式之前出现不需要的子模式,如何检测模式?

时间:2021-04-19 20:15:12

I'm new to regex and I'm trying to use Java to detect a sequence of either: lowercase, uppercase, or digits, but not JUST digits separated by periods. Restriction: No consecutive periods.

我是regex的新手,我正在尝试使用Java来检测一个序列:小写,大写或数字,但不是由句点分隔的JUST数字。限制:没有连续的期间。

The sample String I have is: @@@951.324.1@@@foo1.bar2.123proccess.this.subString

我拥有的示例字符串是:@@@ 951.324.1 @@@ foo1.bar2.123proccess.this.subString

I currently have the following regex: ((\p{Alnum})+\.)+(\p{Alnum})+

我目前有以下正则表达式:((\ p {Alnum})+ \。)+(\ p {Alnum})+

I'm trying to have the pattern recognize foo1.bar2.123proccess.this.subString but my regex gives me 951.324.1 since it's a sub-pattern of the pattern I defined.

我试图让模式识别foo1.bar2.123proccess.this.subString,但我的正则表达式给了我951.324.1,因为它是我定义的模式的子模式。

How would I go about detecting the subString foo1.bar2.123proccess.this.subString

我将如何检测subString foo1.bar2.123proccess.this.subString

I would imagine the general nature would be: The entire returned String should have at least 1 lowercase or uppercase char, but I'm hopelessly confused on how I would detect that in the String.

我想象的一般性质是:整个返回的String应该至少有1个小写或大写字符,但我绝对不知道如何在String中检测到它。

2 个解决方案

#1


2  

[a-zA-Z\d.]*[a-zA-Z][a-zA-Z\d.]*

This can be split into 3 parts:

这可以分为3部分:

[a-zA-Z\d.]* // optional sequence of letters/numbers/dots
[a-zA-Z] // MUST have a letter
[a-zA-Z\d.]* // optional sequence of letters/numbers/dots

Basically, "sandwiching" things that are required in optional things.

基本上,“夹住”可选事物所需的东西。

Try it here: https://regex101.com/r/VT4t2x/1

试试这里:https://regex101.com/r/VT4t2x/1

#2


0  

You may use

你可以用

String rx = "\\d+(?:\\.\\d+)+|(\\p{Alnum}+(?:\\.\\p{Alnum}+)+)";

See the regex demo (pattern adjusted since regex101 does not support Java POSIX character class syntax)

请参阅regex演示(由于regex101不支持Java POSIX字符类语法,因此调整了模式)

The point is to match and skip dot-separated digit chunks, and only match and capture what you need. See Java demo:

重点是匹配并跳过以点分隔的数字块,并且只匹配并捕获您需要的内容。请参阅Java演示:

String s = "@@@951.324.1@@@abc.123";
String rx = "\\d+(?:\\.\\d+)+|(\\p{Alnum}+(?:\\.\\p{Alnum}+)+)";
Pattern pattern = Pattern.compile(rx);
Matcher matcher = pattern.matcher(s);
while (matcher.find()){
    if (matcher.group(1) != null) {
        System.out.println(matcher.group(1)); 
    }
}  // => abc.123

#1


2  

[a-zA-Z\d.]*[a-zA-Z][a-zA-Z\d.]*

This can be split into 3 parts:

这可以分为3部分:

[a-zA-Z\d.]* // optional sequence of letters/numbers/dots
[a-zA-Z] // MUST have a letter
[a-zA-Z\d.]* // optional sequence of letters/numbers/dots

Basically, "sandwiching" things that are required in optional things.

基本上,“夹住”可选事物所需的东西。

Try it here: https://regex101.com/r/VT4t2x/1

试试这里:https://regex101.com/r/VT4t2x/1

#2


0  

You may use

你可以用

String rx = "\\d+(?:\\.\\d+)+|(\\p{Alnum}+(?:\\.\\p{Alnum}+)+)";

See the regex demo (pattern adjusted since regex101 does not support Java POSIX character class syntax)

请参阅regex演示(由于regex101不支持Java POSIX字符类语法,因此调整了模式)

The point is to match and skip dot-separated digit chunks, and only match and capture what you need. See Java demo:

重点是匹配并跳过以点分隔的数字块,并且只匹配并捕获您需要的内容。请参阅Java演示:

String s = "@@@951.324.1@@@abc.123";
String rx = "\\d+(?:\\.\\d+)+|(\\p{Alnum}+(?:\\.\\p{Alnum}+)+)";
Pattern pattern = Pattern.compile(rx);
Matcher matcher = pattern.matcher(s);
while (matcher.find()){
    if (matcher.group(1) != null) {
        System.out.println(matcher.group(1)); 
    }
}  // => abc.123