如何正确使用java模式对象来匹配字符串模式
我编写了一段代码,可以执行几个字符串操作,包括检查给定字符串是否与某个正则表达式匹配。它在70000个输入下运行得很好,但当我迭代运行它进行五次交叉验证时,它开始给我内存不足的错误。可能我必须分配更多的内存,但我有一种感觉,我可能写了一个效率低下的代码,所以我想再次检查我是否没有犯任何明显的错误如何正确使用java模式对象来匹配字符串模式,java,regex,string,out-of-memory,Java,Regex,String,Out Of Memory,我编写了一段代码,可以执行几个字符串操作,包括检查给定字符串是否与某个正则表达式匹配。它在70000个输入下运行得很好,但当我迭代运行它进行五次交叉验证时,它开始给我内存不足的错误。可能我必须分配更多的内存,但我有一种感觉,我可能写了一个效率低下的代码,所以我想再次检查我是否没有犯任何明显的错误 static Pattern numberPattern = Pattern.compile("^[a-zA-Z]*([0-9]+).*"); public static boole
static Pattern numberPattern = Pattern.compile("^[a-zA-Z]*([0-9]+).*");
public static boolean someMethod(String line) {
String[] tokens = line.split(" ");
for(int i=0; i<tokens.length; i++) {
tokens[i] = tokens[i].replace(",", "");
tokens[i] = tokens[i].replace(";", "");
if(numberPattern.matcher(tokens[i]).find()) return true;
}
return false;
}
哪种方式内存效率更高?它们看起来足够有效吗?任何建议都将不胜感激
编辑:
对不起,我有一个错误的代码,我打算在发布这个问题之前修改它,但在最后一分钟我忘记了。但问题是我有很多类似的操作,除了示例代码没有意义之外,我想知道regexp比较部分是否有效
感谢您的所有评论,我将按照建议查看并修改代码 是的,此代码确实效率低下,因为一旦发现
match=true,您可以立即返回代码>(无需继续循环)
此外,您确定需要将该行拆分为标记吗?为什么不只检查一次正则表达式
最后,如果所有比较检查都失败,则应返回false
(最后一行)。是的,此代码确实效率低下,因为一旦发现match=true,您可以立即返回代码>(无需继续循环)
此外,您确定需要将该行拆分为标记吗?为什么不只检查一次正则表达式
最后,如果所有比较检查都失败,您应该返回false
(最后一行)。除了@alfasin在回答中提到的内容外,您应该避免重复代码;重写以下内容:
{
tokens[i] = tokens[i].replace(",", "");
tokens[i] = tokens[i].replace(";", "");
}
进入:
请在它成为.split()
之前计算它,这样操作就不必在循环中重复:
String[] tokens = line.replaceAll(",|;", "").split(" ");
^^^^^^^^^^^^^^^^^^^^^^
Edit:在看了你的代码一段时间后,我想我有了一个更好的解决方案,使用regex;)强>
\b
是单词边界
- 它在单词的边界处声明位置(行首+空格后)
代码演示标准输出:
foo不匹配
条形图不匹配
bar1不匹配
foo baz bar 1 lolz不匹配
密码_01不匹配
除了@alfasin在他的回答中提到的以外,您应该避免重复代码;重写以下内容:
{
tokens[i] = tokens[i].replace(",", "");
tokens[i] = tokens[i].replace(";", "");
}
进入:
请在它成为.split()
之前计算它,这样操作就不必在循环中重复:
String[] tokens = line.replaceAll(",|;", "").split(" ");
^^^^^^^^^^^^^^^^^^^^^^
Edit:在看了你的代码一段时间后,我想我有了一个更好的解决方案,使用regex;)强>
\b
是单词边界
- 它在单词的边界处声明位置(行首+空格后)
代码演示标准输出:
foo不匹配
条形图不匹配
bar1不匹配
foo baz bar 1 lolz不匹配
密码_01不匹配
好的,首先,试着再看一下你的代码。。。它将始终返回“真实”值!您没有读取'match'变量,只是输入值
第二,字符串是不可变的,所以,每次拆分时,都会创建另一个实例。。。为什么不尝试创建一个模式,使您想要的匹配忽略逗号和分号?我不确定,但我认为它会占用您更少的内存…好吧,首先,请再次查看您的代码。。。它将始终返回“真实”值!您没有读取'match'变量,只是输入值
第二,字符串是不可变的,所以,每次拆分时,都会创建另一个实例。。。为什么不尝试创建一个模式,使您想要的匹配忽略逗号和分号?我不确定,但我认为它会占用您更少的内存…您可以将其全部放在正则表达式中,而不是更改文本并将其拆分
// the \\b means it must be the start of the String or a word
static Pattern numberPattern = Pattern.compile("\\b[a-zA-Z,;]*[0-9,;]*[0-9]");
// return true if the string contains
// a number which might have letters in front
public static boolean someMethod(String line) {
return numberPattern.matcher(line).find());
}
您可以将文本全部放在正则表达式中,而不是修改并拆分文本
// the \\b means it must be the start of the String or a word
static Pattern numberPattern = Pattern.compile("\\b[a-zA-Z,;]*[0-9,;]*[0-9]");
// return true if the string contains
// a number which might have letters in front
public static boolean someMethod(String line) {
return numberPattern.matcher(line).find());
}
每次调用split(“”)
时,它都会创建自己的模式,用于在空间上进行拆分。在担心性能之前,我会确保代码正确运行并有意义。你做了所有的工作,却忽略了结果。每次调用split(“”
)时,它都会创建自己的模式,用于在空间上进行拆分。在担心性能之前,我会确保代码正确运行并有意义。您完成了所有这些工作,但忽略了结果。每次调用.replaceAll(“,|”)
都将为,|创建自己的模式代码>正则表达式和匹配器,它们将尝试从处理过的字符串中查找并删除此模式。@Pshemo!!!检查.replace(“,”)
的每次调用也会为正则表达式/,/
创建其模式
,但在本例中,我们为”、“
和”;“
执行了两次,因此.replaceAll()
仍然优于.replaceAll>。每次调用.replaceAll(“,|”)
将为创建自己的模式代码>正则表达式和匹配器,它们将尝试从处理过的字符串中查找并删除此模式。@Pshemo!!!检查.replace(“,”,“)
的每次调用也会为正则表达式/,/
创建其模式
,但在本例中,我们为,“
和”;“
执行了两次,因此.replaceAll()
仍然更可取。不过,这并没有真正将其全部放在正则表达式中。请参见tokens[i]=tokens[i]。替换(“,”,”);令牌[i]=令牌[i]。替换(“;”,“”)代码>@Unihedron我想添加它们,谢谢你的更正。不,这行不通。参见案例“;”