gpt4 book ai didi

java - 如何通过添加更多字符来判断字符串是否可以匹配正则表达式

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:17:03 25 4
gpt4 key购买 nike

这是一个棘手的问题,也许最终没有解决方案(或者至少不是一个合理的解决方案)。我想要一个特定于 Java 的示例,但如果它可以完成,我想我可以用任何示例来完成。

我的目标是找到一种方法来了解从输入流中读取的字符串是否仍然可以匹配给定的正则表达式模式。或者,换句话说,读取流直到我们得到一个绝对不会匹配这种模式的字符串,无论您向它添加多少字符。

实现此目的的极简简单方法的声明可能类似于:

boolean couldMatch(CharSequence charsSoFar, Pattern pattern);

这样的方法将返回 true 如果 charsSoFar 在添加新字符时仍然可以匹配模式,或者如果没有添加则返回 false即使添加新字符,也有机会匹配它。

举一个更具体的例子,假设我们有一个 float 模式,如 "^([+-]?\\d*\\.?\\d*)$"

使用这样的模式,couldMatch 将为以下示例charsSoFar 参数返回true:

"+"  
"-"
"123"
".24"
"-1.04"

依此类推,因为您可以继续为所有这些添加数字,并在前三个数字中加上一个点。

另一方面,从前一个派生的所有这些示例都应返回 false:

"+A"  
"-B"
"123z"
".24."
"-1.04+"

乍一看,无论您向其中添加多少个字符,这些都永远不会符合上述模式。

编辑:

我现在添加我当前的非正则表达式方法,以使事情更清楚。

首先,我声明以下功能接口(interface):

public interface Matcher {
/**
* It will return the matching part of "source" if any.
*
* @param source
* @return
*/
CharSequence match(CharSequence source);
}

然后,之前的函数将被重新定义为:

boolean couldMatch(CharSequence charsSoFar, Matcher matcher);

float 的(草拟)匹配器可能看起来像(注意这不支持开头的 + 号,只支持 -):

public class FloatMatcher implements Matcher {
@Override
public CharSequence match(CharSequence source) {
StringBuilder rtn = new StringBuilder();

if (source.length() == 0)
return "";

if ("0123456789-.".indexOf(source.charAt(0)) != -1 ) {
rtn.append(source.charAt(0));
}

boolean gotDot = false;
for (int i = 1; i < source.length(); i++) {
if (gotDot) {
if ("0123456789".indexOf(source.charAt(i)) != -1) {
rtn.append(source.charAt(i));
} else
return rtn.toString();
} else if (".0123456789".indexOf(source.charAt(i)) != -1) {
rtn.append(source.charAt(i));
if (source.charAt(i) == '.')
gotDot = true;
} else {
return rtn.toString();
}
}
return rtn.toString();
}
}

在 couldMatch 方法的省略体中,它只会迭代调用 matcher.match() 并在源参数末尾添加一个新字符并返回 true,而返回的 CharSequence 等于源参数,否则返回 false一旦不同(意味着添加的最后一个字符破坏了匹配)。

最佳答案

你可以很容易地做到这一点

boolean couldMatch(CharSequence charsSoFar, Pattern pattern) {
Matcher m = pattern.matcher(charsSoFar);
return m.matches() || m.hitEnd();
}

如果序列不匹配,引擎没有到达输入的末尾,则意味着末尾之前有一个矛盾的字符,在末尾添加更多字符不会消失。

或者,作为 the documentation说:

Returns true if the end of input was hit by the search engine in the last match operation performed by this matcher.

When this method returns true, then it is possible that more input would have changed the result of the last search.

这也被 Scanner 使用内部类,以确定它是否应该从源流加载更多数据以进行匹配操作。

将上述方法与您的示例数据一起使用

Pattern fpNumber = Pattern.compile("[+-]?\\d*\\.?\\d*");
String[] positive = {"+", "-", "123", ".24", "-1.04" };
String[] negative = { "+A", "-B", "123z", ".24.", "-1.04+" };
for(String p: positive) {
System.out.println("should accept more input: "+p
+", couldMatch: "+couldMatch(p, fpNumber));
}
for(String n: negative) {
System.out.println("can never match at all: "+n
+", couldMatch: "+couldMatch(n, fpNumber));
}
should accept more input: +, couldMatch: true
should accept more input: -, couldMatch: true
should accept more input: 123, couldMatch: true
should accept more input: .24, couldMatch: true
should accept more input: -1.04, couldMatch: true
can never match at all: +A, couldMatch: false
can never match at all: -B, couldMatch: false
can never match at all: 123z, couldMatch: false
can never match at all: .24., couldMatch: false
can never match at all: -1.04+, couldMatch: false

当然,这并没有说明将不匹配内容变成匹配内容的可能性。您仍然可以构建任何其他字符都无法匹配的模式。但是,对于像 float 格式这样的普通用例,这是合理的。

关于java - 如何通过添加更多字符来判断字符串是否可以匹配正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53062616/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com