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.
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
}