1

I have a TextWatcher that checks if a URL is valid. A URL is valid if it fulfills the URL format where "http", "https", "www", etc. are optional. It is also valid if it's an empty string. The EditText will display an error message if the URL is invalid. This is my current implementation:

private TextWatcher websiteLinkWatcher = new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        if(websiteLayout.getError() != null) websiteLayout.setErrorEnabled(false);
    }

    @Override
    public void afterTextChanged(Editable s) {
        String websiteFormat = "^(|https?:\\/\\/[\\w\\-_]+(\\.[\\w\\-_]+)+([\\w\\-\\.,@?^=%&:/~\\+#]*[\\w\\-\\@?^=%&/~\\+#])?){0,140}$";
        if(s.toString().trim().length() > 140 || !s.toString().matches(websiteFormat)) {
            Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    websiteLayout.setErrorEnabled(true);
                    websiteLayout.setError("The provided website is not valid.");
                }
            }, 2000);
            saveEnabled.setBackgroundColor(getResources().getColor(R.color.grey200));
            saveEnabled.setClickable(false);
            // disable
        }
        else {
            saveEnabled.setBackgroundColor(getResources().getColor(R.color.blue500));
            saveEnabled.setClickable(true);
            // enable
        }
        return;
    }
};

The regex is very inconsistent. Its only advantage is it works with an empty string (i.e. no error message is displayed). Currently, http://example.com, https://example.com, an empty string are accepted. https://www.example.com is sometimes accepted or rejected. www.example.com and example.com are rejected.

Bargain23
  • 1,863
  • 3
  • 29
  • 50

1 Answers1

1
String pattern = "(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9]\.[^\s]{2,})";

Will match the following cases

  • http://www.foufos.gr
  • https://www.foufos.gr
  • http://foufos.gr
  • http://www.foufos.gr/kino
  • http://www.t.co
  • http://t.co
  • http://werer.gr
  • www.foufos.gr
  • www.mp3.com
  • www.t.co

Will NOT match the following

  • www.foufos
  • http://www.foufos
  • http://foufos
  • www.mp3#.com
  • www.foufos-.gr
  • www.-foufos.gr

Concerning empty string, first check if it is empty and then check for pattern:

if(yourstring.length() == 0 ||  yourstring.matches(pattern)) {
  // do something
}else{
   // show validation warning
}

source

Misha Akopov
  • 12,241
  • 27
  • 68
  • 82
  • It works initially, but when I start editing the text and delete everything, the error message prompt appears. There should be no error message for empty strings. – Bargain23 Jan 03 '18 at 13:57
  • I doubt it, in `if` statement you check if it is empty, the url is valid, or if pattern matches. How could the error occur when `yourstring.length() == 0 ` check. Please check the if statement if you have NOT statement - ! . – Misha Akopov Jan 03 '18 at 14:07
  • @Bargain23 I have updated if statement, please look at it when you should show warning – Misha Akopov Jan 03 '18 at 14:10