如何在java中限制匹配器只匹配所需的字符串?以下是我尝试的代码,但是预期的匹配应该像" Invoice Received"但它只打印" Invoice"在控制台上。
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class JavaTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
List<String> actionList = new ArrayList<String>();
actionList.add("Invoice");
actionList.add("Invoice Received");
List<String> notes = new ArrayList<String>();
notes.add("Invoice Received123");
for (String note : notes) {
for (String action : actionList) {
Pattern pattern = Pattern.compile(action);
Matcher matcher = pattern.matcher(note);
if(matcher.find()) {
System.out.println("Update History As : "+action);
}
}
}
}
}
答案 0 :(得分:1)
if(matcher.find()) {
System.out.println("Update History As : "+action);
break;
}
这破坏了你的代码。从字面上看。当模式匹配时,break
语句退出内部for
循环。因此,Invoice Recieved
永远不会有机会匹配。
最初这是解释的问题,但问题已经成为关于这个特定问题的流量控制。作为建议的解决方案,这里是Note
对象没有多态的示例,而是控制代码。
public class Note {
public static final int INVOICE = 1;
public static final int INVOICE_RECEIVED = 2;
public int noteType;
public String userText;
public Note(int noteType, String userText) {
this.noteType = noteType;
this.userText = userText;
}
public void doSomething() {
switch(noteType) {
case INVOICE:
// do something with the INVOICE type
break;
case INVOICE_RECEIVED:
// do something with the INVOICE_RECEIVED type
break;
}
}
}
然后,您可以按Note
创建一个收到发票的Note newNote = new Note(Note.INVOICE_RECEIVED, "this is some user text");
对象,并将它们添加到列表中,类似于您正在执行的操作,并相应地处理它们。根据您的音符数量,多态设计可能会更好,或者至少更清晰。但这是使用控制代码的方式。
答案 1 :(得分:0)
您需要订购您正在寻找的模式,以便一种模式的前缀始终位于该模式之后。具体而言:
List<String> actionList = new ArrayList<String>();
actionList.add("Invoice Received"); /* Make this take precedence... */
actionList.add("Invoice"); /* ... over this. */
然后将break
放回到您的比赛案例中,或者每个“已开票的已收到”说明也将作为“发票”说明处理:
if(matcher.find()) {
System.out.println("Update History As : "+action);
break;
}
一般来说,这种系统很容易受到漏洞的影响。如果您对此流程的输入有任何控制权,请对其进行修改,以使备注类型明确,而不是从其内容中猜到。