我的直觉方法是使用 DocumentFilter 并根据测试字符串的长度修改您正在测试的正则表达式。因此,如果您的测试字符串长度为 10 个字符,那么您用来测试它的正则表达式是"(\\d{2})-bk\\d{3}\\."
or "\\d\\d\\d-bk\\d\\d\\d\\d\\."
。这会通过"123-bk0001."
,但会失败"123-bk000a."
。
您要处理的每个正则表达式都需要进行一些自定义(例如,根据测试字符串的长度将括号放在正则表达式中的正确位置),但我认为没有办法使正则表达式动态化基于长度(这是你所追求的)。
import javax.swing.*;
import javax.swing.text.*;
public class JTextFieldSuperVerified extends Box{
public JTextFieldSuperVerified() {
super(BoxLayout.Y_AXIS);
final JTextField textBox = new JTextField(20);
((AbstractDocument)textBox.getDocument()).setDocumentFilter(new DocumentFilter(){
public void insertString(DocumentFilter.FilterBypass fb,int offset,String string,AttributeSet attr) throws BadLocationException{
StringBuilder newString = new StringBuilder(textBox.getText());
//Recreate the insert for testing
newString.insert(offset, string);
if(verifyText(newString.toString())){
fb.insertString(offset, string, attr);
}
}
public void remove(DocumentFilter.FilterBypass fb, int offset, int length) throws BadLocationException{
StringBuilder newString = new StringBuilder(textBox.getText());
//Recreate the delete for testing
newString.delete(offset, offset + length);
if(verifyText(newString.toString())){
fb.remove(offset, length);
}
}
public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException{
StringBuilder newString = new StringBuilder(textBox.getText());
//Recreate the replace for testing
newString.replace(offset, offset + length, text);
if(verifyText(newString.toString())){
fb.replace(offset, length, text, attrs);
}
}
//make sure the change is allowed
public boolean verifyText(String s){
boolean result = true;
//Our basic regex to test
StringBuilder regexPattern = new StringBuilder("\\d\\d\\d-bk\\d\\d\\d\\d\\.\\1");
if(s.length() < 15){
//How we modify the regex based on how long the string we're testing is
if(s.length() < 4)
regexPattern.delete(s.length() * 2, regexPattern.length());
else if(s.length() < 7)
regexPattern.delete(s.length() + 3, regexPattern.length());
else if(s.length() < 12)
regexPattern.delete((s.length() - 3) * 2 + 3, regexPattern.length());
else if(s.length() < 15){
regexPattern.insert((s.length() - 11) * 2, ')');
regexPattern.insert(0, '(');
}
System.out.println(regexPattern.toString());
result = s.matches(regexPattern.toString());
}else{
//Fail everything over 14 chars
result = false;
}
return result;
}
});
add(textBox);
}
public static void main(String[] args){
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JTextFieldSuperVerified());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}