模式匹配bug

时间:2015-12-23 14:59:14

标签: java android

调用静态方法时,我在Android中发现了一个错误。

  

Pattern.matches(String pattern, String value)

以下是错误详情:

  

让参数模式=" ^[a-zA-Z0-9]([\\-a-zA-Z0-9_\\u4e00-\\u9fa5]*)+&#34 ;;

     

让value成为包含符号" @"的长字符串; (最后几乎每次都会崩溃),例如" Abcjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj@";

     

致电Pattern.matches(pattern, value);

此方法卡住,不返回任何内容。

  

如果输入字符串很短,例如" Abc@",那很好并返回false。

     

如果输入一个短字符串,例如" Abc@",那么继续使字符串更长,就像" Abc@jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj@一样,它很好并且返回false

在我的应用程序中,当我在EditText中执行此操作并单击按钮以执行Pattern.mathes(模式,值).UI将不响应,然后应用程序将崩溃。

当我想要过滤用户的输入时,我发现这个错误正在工作,然后我在自己的应用程序中编写一个简单的测试用例来重复发现这个错误(请参阅btnTestInput()方法),这是我的应用程序代码。

这是mainActivity XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.tyouter.timecat.ui.activity.MainActivity"
    android:orientation="vertical">

    <EditText
        android:id="@+id/edtTestInputFilter"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="none" />

    <Button
        android:id="@+id/btnTestInput"
        android:text="@string/activity_main_test_input_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

这是mainActivity.class:

@EActivity(R.layout.activity_main)
@OptionsMenu(R.menu.menu_main)
public class MainActivity extends BaseActivity {

    @ViewById
    EditText edtTestInputFilter;

    @ViewById
    Button btnTestInput;

    @Bean
    MainController controller;

    MainAdapter adapter;

    @AfterViews
    void init() {
        TimeCatApplication.BUS.register(this);
    }

    @OptionsItem
    void menuSettings() {

    }

    @OptionsItem
    void menuAbout() {
        controller.onMenuAboutClicked(this);
    }

    @Subscribe(threadMode = ThreadMode.MainThread)
    public void onEventMainThread(TestEventBusEvent event) {
        T.showLong(this, getResources().getString(R.string.test_event_success));
    }

    @Override
    protected void initVariables() {

    }

    @Override
    protected void initViews(Bundle savedInstance) {

    }

    @Override
    protected void loadData() {

    }

    @Click
    void btnTestInput() {
        if (InputFilter.projectNameMatches(getTest())) {
            T.showLong(this, "pass");
        }else {
            T.showLong(this, "fail");
        }
    }

    private String getTest() {
        return edtTestInputFilter.getText().toString();
    }
}

这是InputFilter.class:

public class InputFilter {
    static String mProjectName = "^[a-zA-Z0-9]([\\-a-zA-Z0-9_\\u4e00-\\u9fa5]*)+";

    public static boolean matches(String pattern, String value) {
        return Pattern.matches(pattern, value);
    }

    public static boolean projectNameMatches(String projectName) {
        return matches(mProjectName, projectName);
    }
}

我的Java版本:1.8.0_51。

我的Android构建工具和sdk:23.0.1 23。

1 个答案:

答案 0 :(得分:2)

这不是错误,它是catastrophic backtracking。您的模式中有嵌套的量词。更改为

...
lol1.Open()
...
lol2.Open()
...
lol3.Open()
...
lol4.Open()
...

您不需要在模式中的第一个String pattern = "[a-zA-Z0-9][-a-zA-Z0-9_\\u4e00-\\u9fa5]*"; ,因为您可以在^方法中使用它,该方法要求整个字符串都与模式匹配。