1

プログラムJTextField内で、特定のPattern.

JFormattedTextField私はのマスクについて知っていますが、それは私がここで望んでいるものではありません

新しい入力ごとに、特定の正規表現パターンのフローに準拠している場合にのみ、テキストは変更を受け入れる必要があります。

入力がそれ自体の一部を受け取る必要がある場合など、「正規表現が要求される」状況のため、これは正規表現で行う必要があります。これは、次の例でよりよく理解できます。

私の正規表現が"(\\d{2})-bk\\d{3}\\.\\1". が入力"123-bk001."された場合、次に入力される文字は最初のグループと等しくなければなりません。つまり、入力された 3 文字は123、それぞれが等しい場合にのみ受け入れられる必要があります。「456-bk404」の入力。代わりに次の文字が必要になり"456"ます。

どうすればいいですか?


編集:

この例は、正規表現なしでは解決が難しい状況の 1 つを説明するためのものであり、私の実際の使用はそれに限定されません。したがって、可能であれば、回答は、この例に固有のものではなく、(質問のタイトルの時点で) より幅広い使いやすさのものにする必要があります。

しかし、それが不可能な場合、または少数 (3 ~ 5 件) の異なるケースに対して特定のソリューションを実装するよりも難しい場合は、お気軽にお知らせください。

4

2 に答える 2

2
于 2012-11-28T17:16:28.860 に答える
0

私の直感的なアプローチは、DocumentFilterを使用し、テスト文字列の長さに基づいてテスト対象の正規表現を変更することです。したがって、テスト文字列の長さが10文字の場合、テストに使用する正規表現はまたは"(\\d{2})-bk\\d{3}\\."です"\\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);
    }
}
于 2012-12-04T18:02:25.820 に答える