我正在学习正则表达式,并且我有这段代码片段:
baseUrl
尝试另一种方式:
private static final String FILE_BEGINNING_PATTERN = "^(,Share %)";
public static void main(String[] args) {
String str = ",Share %,\"Date Purchased\",Display Name,Address,Phone,Fax,Mobile,Email,";
Matcher beginningFileMatcher = Pattern.compile(FILE_BEGINNING_PATTERN).matcher(str);
if (beginningFileMatcher.find()) {
System.out.println("Regex match!");
}
// find() method starts at the beginning of this matcher's region, or, if
// a previous invocation of the method was successful and the matcher has
// not since been reset, at the first character not matched by the previous
// match.
//
int count = 0;
while (beginningFileMatcher.find()) { // find not match, we need beginningFileMatcher.reset() but its not
// thread-safe.
count++;
System.out.println("COUNT ++++++++++++++ :" + count);
}
}
我已经在上面的片段中对此问题发表了评论。有谁能解释为什么?非常感谢!
答案 0 :(得分:4)
问题是您每次都在Matcher
条件下创建一个新的if
实例,并且while
循环在这里阻塞:
if (beginningFilePattern.matcher(s).find()) {
在这里:
while (beginningFilePattern.matcher(s).find())
通过创建Matcher
的新实例,您将失去该状态的先前状态,并且每次都启动匹配操作。
还请注意在if
循环之前删除while
条件,以使count
正确。
您可以使用以下代码解决此问题:
String str = ",Share %,\"Date Purchased\",Display Name,Address,Phone,Fax,Mobile,Email,";
Matcher beginningFileMatcher = Pattern.compile(FILE_BEGINNING_PATTERN).matcher(str);
// find() method starts at the beginning of this matcher's region, or, if
// a previous invocation of the method was successful and the matcher has
// not since been reset, at the first character not matched by the previous
// match.
//
int count = 0;
while (beginningFileMatcher.find()) { // find not match, we need beginningFileMatcher.reset() but its not
if (count == 0)
System.out.println("Regex match!");
// thread-safe.
count++;
System.out.println("COUNT ++++++++++++++ :" + count);
}
//try another way.
String s = ",Share %,\"Date Purchased\",Display Name,Address,Phone,Fax,Mobile,Email,";
Pattern beginningFilePattern = Pattern.compile(FILE_BEGINNING_PATTERN);
Matcher matcher = beginningFilePattern.matcher(s);
int countCount = 0;
while (matcher.find()) { // make sure to use matcher object
if (countCount == 0)
System.out.println("Thread-safe regex match!");
countCount++;
System.out.println("COUNT ++++++++++++++ :" + countCount);
}
答案 1 :(得分:1)
每个版本的代码都有一个不同的问题。
对于版本2(无限循环):在循环中创建匹配器。这意味着在每次迭代中,都会从String的开头开始有一个新的匹配器。因此,对find
的调用将始终返回相同的结果(如果有的话)。
您需要做的第一个解决方案是创建一个匹配器,然后通过循环调用find
来使用它。
问题是您在两个不同的地方致电find
。首先在if
块中,查看您的String中是否有匹配项,然后在循环中。
如果字符串仅包含1个匹配结果怎么办?
if
块中返回countCount
设置为0
COUNT : 0
如果在循环之前不重置匹配器,则需要将if
块中的结果计数到计数器中。这是更改最少的解决方案:
final static String FILE_BEGINNING_PATTERN = "^(,Share %)";
public static void main(String[] args) {
String str = ",Share %,\"Date Purchased\",Display Name,Address,Phone,Fax,Mobile,Email,";
Matcher beginningFileMatcher = Pattern.compile(FILE_BEGINNING_PATTERN).matcher(str);
int count = 0;
if (beginningFileMatcher.find()) {
System.out.println("Regex match!");
count++; // already a match, increment the counter
}
while (beginningFileMatcher.find()) {
count++;
System.out.println("COUNT ++++++++++++++ :" + count);
}
}
另一种方法是删除if块并仅使用while循环。
答案 2 :(得分:0)
重置此匹配器。
重置匹配器将丢弃其所有显式状态信息,并将其附加位置设置为零。匹配器的区域设置为默认区域,即其整个字符序列。该匹配器区域边界的锚定和透明度不受影响。
如果您希望它具有线程安全性,请将其放在10.2
块中
答案 3 :(得分:0)
我认为问题在于,当您调用beginningFilePattern.matcher(s).find()
时,您正在while
条件内创建匹配器的新实例。这些新匹配器中的每一个将从头开始再次检查,而不是尝试查找下一个匹配器。您应该尝试确保reset()
通话威胁的安全性,但保持相同的匹配器实例。