不应考虑字符串末尾的空格或两个数字之间的空格,但它可以在数字之前或之后,但不能在数字之间。 我写了一个正则表达式,但根据我的要求,它并不适用于所有条件。
Pattern pattern =Pattern.compile("\\s(?![\\d\\s]*\\d$)");
Matcher matcher=pattern.matcher(input);
int lastIndex=-1;
while(matcher.find()){
lastIndex=matcher.start());
}
我如何使用正则表达式和任何其他方式在没有 while 循环的情况下获得最后一次出现来实现我的要求? 例子
[email protected] m 5180-3807-3679-8221 612 3/1/2010
^
hello this card number 4444 5555 6666 7777
^
hello this bob
^
您可以使用前瞻断言:
断言候选空格后跟至少一个非空白字符,并且任何进一步的空格(如果有的话)被数字包围或出现在字符串的末尾。
对于“周围”条件,您可以再次使用环视断言。此正则表达式将仅匹配被数字包围或出现在字符串末尾且前面有数字的空格:
"(?<=\\d)\\s+(?!\\D)"
。只有那种类型的空白和\\s*$
将被允许after与此断言的潜在匹配空间:
"(?=\\S+((?<=\\d)\\s+(?!\\D)\\S*)*\\s*$)"
现在我们可以添加候选空间本身的要求:它要么前面没有数字,要么后面没有数字:
"(?:\\s(?=\\D)|(?<!\\d)\\s)(?=\\S+((?<=\\d)\\s+(?!\\D)\\S*)*\\s*$)"
代码:
Pattern pattern = Pattern.compile("(?:\\s(?=\\D)|(?<!\\d)\\s)(?=\\S+((?<=\\d)\\s+(?!\\D)\\S*)*\\s*$)");
Matcher matcher = pattern.matcher(input);
int lastIndex=-1;
if (matcher.find()) { // We only expect at most one match
lastIndex = matcher.start();
// Do something with lastIndex
}
你可以试试这个正则表达式模式:
(\s)(?:[\d\s]+|\w+)$
Pattern pattern = Pattern.compile("(\\s)(?:[\\d\\s]+|\\w+)$");
Matcher matcher = pattern.matcher(input);
int lastIndex = -1;
if (matcher.find()) {
lastIndex = matcher.start();
}
见正则表达式演示这里
如果您只想最后一次出现,可以使用
.*
并让点匹配换行符以查找所有行中的最后一次出现。请注意,\s
也匹配换行符。
(?s)^.*(\s(?<!\d.)(?=\d)|\s(?<=\d.)(?!\d|\s*$)|\s(?<=[^\d\s].)(?=[^\d\s]))
然后您可以使用
matcher.find()
并使用 matcher.start(1)
从第 1 组获取索引
String regex = "(?s)^.*(\\s(?<!\\d.)(?=\\d)|\\s(?<=\\d.)(?!\\d|\\s*$)|\\s(?<=[^\\d\\s].)(?=[^\\d\\s]))";
String string = "[email protected] m 5180-3807-3679-8221 612 3/1/2010\n\n"
+ "hello this card number 4444 5555 6666 7777\n\n"
+ "hello this bob";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(string);
if (matcher.find()) {
System.out.println("[" + matcher.group(1) + "]");
System.out.println(matcher.start(1));
}
输出
[ ]
109
如果你有单行,你可以使用
\h
来匹配水平空白字符。
^.*(\h(?<!\d.)(?=\d)|\h(?<=\d.)(?!\d|\h*$)|\h(?<=[^\d\h].)(?=[^\d\h]))