Android / Java: Check if url is valid youtube url - java

I want to check if an url is valid youtube url so that I can shown in view otherwise I will hide the view.
Is there any regular expression in Java that can help me to check if url is valid. Currently I am using this regex but I guess it's not the one I want:
String youTubeURl = "https://www.youtube.com/watch?v=Btr8uOU0BkI";
String pattern = "https?:\\/\\/(?:[0-9A-Z-]+\\.)?(?:youtu\\.be\\/|youtube\\.com\\S*[^\\w\\-\\s])([\\w\\-]{11})(?=[^\\w\\-]|$)(?![?=&+%\\w]*(?:['\"][^<>]*>|<\\/a>))[?=&+%\\w]*";
if (!youTubeURl.isEmpty() && youTubeURl.matches(pattern)) {
/// Valid youtube URL
}
else{
// Not Valid youtube URL
}

This works for me.
public static boolean isYoutubeUrl(String youTubeURl)
{
boolean success;
String pattern = "^(http(s)?:\\/\\/)?((w){3}.)?youtu(be|.be)?(\\.com)?\\/.+";
if (!youTubeURl.isEmpty() && youTubeURl.matches(pattern))
{
success = true;
}
else
{
// Not Valid youtube URL
success = false;
}
return success;
}
If you want to retrieve the Youtube videoId you can use the following function.
public static String getVideoIdFromYoutubeUrl(String youtubeUrl)
{
/*
Possibile Youtube urls.
http://www.youtube.com/watch?v=WK0YhfKqdaI
http://www.youtube.com/embed/WK0YhfKqdaI
http://www.youtube.com/v/WK0YhfKqdaI
http://www.youtube-nocookie.com/v/WK0YhfKqdaI?version=3&hl=en_US&rel=0
http://www.youtube.com/watch?v=WK0YhfKqdaI
http://www.youtube.com/watch?feature=player_embedded&v=WK0YhfKqdaI
http://www.youtube.com/e/WK0YhfKqdaI
http://youtu.be/WK0YhfKqdaI
*/
String pattern = "(?<=watch\\?v=|/videos/|embed\\/|youtu.be\\/|\\/v\\/|\\/e\\/|watch\\?v%3D|watch\\?feature=player_embedded&v=|%2Fvideos%2F|embed%\u200C\u200B2F|youtu.be%2F|%2Fv%2F)[^#\\&\\?\\n]*";
Pattern compiledPattern = Pattern.compile(pattern);
//url is youtube url for which you want to extract the id.
Matcher matcher = compiledPattern.matcher(youtubeUrl);
if (matcher.find()) {
return matcher.group();
}
return null;
}

You should use
Patterns.WEB_URL.matcher(youTubeURl).matches()
It will return True if URL is valid and false if URL is invalid.

Use android.webkit.URLUtil.isValidUrl(java.lang.String) to check if url is valid. And then you can check if url contains Youtube string.
Like
private boolean isValidUrl(String url) {
if (url == null) {
return false;
}
if (URLUtil.isValidUrl(url)) {
// Check host of url if youtube exists
Uri uri = Uri.parse(url);
if ("www.youtube.com".equals(uri.getHost())) {
return true;
}
// Other way You can check into url also like
//if (url.startsWith("https://www.youtube.com/")) {
//return true;
//}
}
// In other any case
return false;
}

In order to achieve what you want you should use this Regex like so:
private static final Pattern youtubePattern = Pattern.compile("^(http(s)?:\/\/)?((w){3}.)?youtu(be|.be)?(\.com)?\/.+");
private boolean isValid = youtubePattern.matcher(youtubeUrl).matches();
where youtubeUrl can be any URL of the following list:
http://youtu.be/t-ZRX8984sc
http://youtube.com/watch?v=iwGFalTRHDA
http://www.youtube.com/watch?v=t-ZRX8984sc
http://www.youtube.com/watch?v=iwGFalTRHDA&feature=related
http://www.youtube.com/embed/watch?feature=player_embedded&v=r5nB9u4jjy4
https://www.youtube.com/channel/UCDZkgJZDyUnqwB070OyP72g
youtube.com/n17B_uFF4cA
youtube.com/iwGFalTRHDA
http://youtu.be/n17B_uFF4cA
https://youtube.com/iwGFalTRHDA
https://youtube.com/channel/UCDZkgJZDyUnqwB070OyP72g
This regex can match any types of URLs related to youtube.com

This doesn't check if URL is valid or not. It only checks for strings "youtube" & "youtu.be" in your URL. Following is the regex
String yourUrl = "https://youtu.be/Xh0-x1RFEOY";
yourUrl.matches(".*(youtube|youtu.be).*")
" .* " at beginning & end means that there could be anything on left & right of the expression(youtube & youtu.be) you are checking.
NOTE: This has nothing to do with the validity of the URL

Related

Java - Replace host in url?

In java, I'd like to replace the Host part of an url with a new Host, where both the host and url are supplied as a string.
This should take into account the fact that the host could have a port in it, as defined in the RFC
So for example, given the following inputs
url: http://localhost/me/out?it=5
host: myserver:20000
I should get the following output from a function that did this correctly
http://myserver:20000/me/out?it=5
Does anyone know of any libraries or routines that do Host replacement in an url correctly?
EDIT: For my use case, I want my host replacement to match what a java servlet would respond with. I tried this out by running a local java web server, and then tested it using curl -H 'Host:superduper.com:80' 'http://localhost:8000/testurl' and having that endpoint simply return the url from request.getRequestURL().toString(), where request is a HttpServletRequest. It returned http://superduper.com/testurl, so it removed the default port for http, so that's what I'm striving for as well.
The Spring Framework provides the UriComponentsBuilder. You can use it like this:
import org.springframework.web.util.UriComponentsBuilder;
String initialUri = "http://localhost/me/out?it=5";
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(initialUri);
String modifiedUri = builder.host("myserver").port("20000").toUriString();
System.out.println(modifiedUri);
// ==> http://myserver:20000/me/out?it=5
Here you need to provide hostname and port in separate calls to get right encoding.
You were right to use java.net.URI. The host and port (and user/password, if they exist) are collectively known as the authority component of the URI:
public static String replaceHostInUrl(String originalURL,
String newAuthority)
throws URISyntaxException {
URI uri = new URI(originalURL);
uri = new URI(uri.getScheme().toLowerCase(Locale.US), newAuthority,
uri.getPath(), uri.getQuery(), uri.getFragment());
return uri.toString();
}
(A URI’s scheme is required to be lowercase, so while the above code can be said not to perfectly preserve all of the original URL’s non-authority parts, an uppercase scheme was never actually legal in the first place. And, of course, it won’t affect the functionality of the URL connections.)
Note that some of your tests are in error. For instance:
assertEquals("https://super/me/out?it=5", replaceHostInUrl("https://www.test.com:4300/me/out?it=5","super:443"));
assertEquals("http://super/me/out?it=5", replaceHostInUrl("http://www.test.com:4300/me/out?it=5","super:80"));
Although https://super/me/out?it=5 is functionally identical to https://super:443/me/out?it=5 (since the default port for https is 443), if you specify an explicit port in a URI, then the URI has a port specified in its authority and that’s how it should stay.
Update:
If you want an explicit but unnecessary port number to be stripped, you can use URL.getDefaultPort() to check for it:
public static String replaceHostInUrl(String originalURL,
String newAuthority)
throws URISyntaxException,
MalformedURLException {
URI uri = new URI(originalURL);
uri = new URI(uri.getScheme().toLowerCase(Locale.US), newAuthority,
uri.getPath(), uri.getQuery(), uri.getFragment());
int port = uri.getPort();
if (port > 0 && port == uri.toURL().getDefaultPort()) {
uri = new URI(uri.getScheme(), uri.getUserInfo(),
uri.getHost(), -1, uri.getPath(),
uri.getQuery(), uri.getFragment());
}
return uri.toString();
}
I quickly tried using java.net.URI, javax.ws.rs.core.UriBuilder, and org.apache.http.client.utils.URIBuilder, and none of them seemed to get the idea of a host header possibly including a port, so they all needed some extra logic from what I could see to make it happen correctly, without the port being "doubled up" at times, and not replaced correctly at other times.
Since java.net.URL doesnt require any extra libs, I used it. I do know that if I was using URL.equals somewhere, that could be a problem as it does DNS lookups possibly, but I'm not so I think it's good, as this covers my use cases, as displayed by the pseudo unit test.
I put together this way of doing it, which you can test it out online here at repl.it !
import java.net.URL;
import java.net.MalformedURLException;
class Main
{
public static void main(String[] args)
{
testReplaceHostInUrl();
}
public static void testReplaceHostInUrl()
{
assertEquals("http://myserver:20000/me/out?it=5", replaceHostInUrl("http://localhost/me/out?it=5","myserver:20000"));
assertEquals("http://myserver:20000/me/out?it=5", replaceHostInUrl("http://localhost:19000/me/out?it=5","myserver:20000"));
assertEquals("http://super/me/out?it=5", replaceHostInUrl("http://localhost:19000/me/out?it=5","super"));
assertEquals("http://super/me/out?it=5", replaceHostInUrl("http://www.test.com/me/out?it=5","super"));
assertEquals("https://myserver:20000/me/out?it=5", replaceHostInUrl("https://localhost/me/out?it=5","myserver:20000"));
assertEquals("https://myserver:20000/me/out?it=5", replaceHostInUrl("https://localhost:19000/me/out?it=5","myserver:20000"));
assertEquals("https://super/me/out?it=5", replaceHostInUrl("https://www.test.com/me/out?it=5","super"));
assertEquals("https://super/me/out?it=5", replaceHostInUrl("https://www.test.com:4300/me/out?it=5","super"));
assertEquals("https://super/me/out?it=5", replaceHostInUrl("https://www.test.com:4300/me/out?it=5","super:443"));
assertEquals("http://super/me/out?it=5", replaceHostInUrl("http://www.test.com:4300/me/out?it=5","super:80"));
assertEquals("http://super:8080/me/out?it=5", replaceHostInUrl("http://www.test.com:80/me/out?it=5","super:8080"));
assertEquals("http://super/me/out?it=5&test=5", replaceHostInUrl("http://www.test.com:80/me/out?it=5&test=5","super:80"));
assertEquals("https://super:80/me/out?it=5&test=5", replaceHostInUrl("https://www.test.com:80/me/out?it=5&test=5","super:80"));
assertEquals("https://super/me/out?it=5&test=5", replaceHostInUrl("https://www.test.com:80/me/out?it=5&test=5","super:443"));
assertEquals("http://super:443/me/out?it=5&test=5", replaceHostInUrl("http://www.test.com:443/me/out?it=5&test=5","super:443"));
assertEquals("http://super:443/me/out?it=5&test=5", replaceHostInUrl("HTTP://www.test.com:443/me/out?it=5&test=5","super:443"));
assertEquals("http://SUPERDUPER:443/ME/OUT?IT=5&TEST=5", replaceHostInUrl("HTTP://WWW.TEST.COM:443/ME/OUT?IT=5&TEST=5","SUPERDUPER:443"));
assertEquals("https://SUPERDUPER:23/ME/OUT?IT=5&TEST=5", replaceHostInUrl("HTTPS://WWW.TEST.COM:22/ME/OUT?IT=5&TEST=5","SUPERDUPER:23"));
assertEquals(null, replaceHostInUrl(null, null));
}
public static String replaceHostInUrl(String url, String newHost)
{
if (url == null || newHost == null)
{
return url;
}
try
{
URL originalURL = new URL(url);
boolean hostHasPort = newHost.indexOf(":") != -1;
int newPort = originalURL.getPort();
if (hostHasPort)
{
URL hostURL = new URL("http://" + newHost);
newHost = hostURL.getHost();
newPort = hostURL.getPort();
}
else
{
newPort = -1;
}
// Use implicit port if it's a default port
boolean isHttps = originalURL.getProtocol().equals("https");
boolean useDefaultPort = (newPort == 443 && isHttps) || (newPort == 80 && !isHttps);
newPort = useDefaultPort ? -1 : newPort;
URL newURL = new URL(originalURL.getProtocol(), newHost, newPort, originalURL.getFile());
String result = newURL.toString();
return result;
}
catch (MalformedURLException e)
{
throw new RuntimeException("Couldnt replace host in url, originalUrl=" + url + ", newHost=" + newHost);
}
}
public static void assertEquals(String expected, String actual)
{
if (expected == null && actual == null)
{
System.out.println("TEST PASSED, expected:" + expected + ", actual:" + actual);
return;
}
if (! expected.equals(actual))
throw new RuntimeException("Not equal! expected:" + expected + ", actual:" + actual);
System.out.println("TEST PASSED, expected:" + expected + ", actual:" + actual);
}
}
I realize this is a pretty old question; but posting a simpler solution in case someone else needs it.
String newUrl = new URIBuilder(URI.create(originalURL)).setHost(newHost).build().toString();
I've added a method to do this in the RawHTTP library, so you can simply do this:
URI uri = RawHttp.replaceHost(oldUri, "new-host");
Added in this commit: https://github.com/renatoathaydes/rawhttp/commit/cbe439f2511f7afcb89b5a0338ed9348517b9163#diff-ff0fec3bc023897ae857b07cc3522366
Feeback welcome, will release it soon.
Or using some regex magic:
public static String replaceHostInUrl(String url, String newHost) {
if (url == null || newHost == null) {
return null;
}
String s = url.replaceFirst("(?i)(?<=(https?)://)(www.)?\\w*(.com)?(:\\d*)?", newHost);
if (s.contains("http://")) {
s = s.replaceFirst(":80(?=/)", "");
} else if (s.contains("https://")) {
s = s.replaceFirst(":443(?=/)", "");
}
Matcher m = Pattern.compile("HTTPS?").matcher(s);
if (m.find()) {
s = s.replaceFirst(m.group(), m.group().toLowerCase());
}
return s;
}

Fast java routine to determine if request URI is within another URL

In a class (Java8), I have a String representing an HTTP URL, e.g. String str1="http://www.foo.com/bar", and another string containing a request URI e.g. str2="/bar/wonky/wonky.html".
What is the fastest way in terms of code execution to determine if str2 is within the context of str1 (e.g. the context is /bar) and then construct the complete url String result = "http://www.foo.com/bar/wonky/wonky.html"?
Well I don't know if there is a faster way to just use String.indexOf(). Here is an approach that I think covers the example you gave (demo):
public static boolean overlap(String a, String b_context) {
//Assume the a URL starts with http:// or https://, the next / is the start of the a_context
int root_index = a.indexOf("/", 8);
String a_context = a.substring(root_index);
String a_host = a.substring(0, root_index);
return b_context.startsWith(a_context);
}
Here is a function that uses the same logic but to combine the two urls if they overlap or throw an exception if they don't
public static String combine(String a, String b_context) {
//Assume the a URL starts with http:// or https://, the next / is the start of the a_context
int root_index = a.indexOf("/", 8);
String a_context = a.substring(root_index);
String a_host = a.substring(0, root_index);
if(b_context.startsWith(a_context)) {
return a_host + b_context;
} else {
throw new RuntimeException("urls do not overlap");
}
}
And here is an example of using them
public static void main(String ... args) {
System.out.println(combine("http://google.com/search", "/search?query=Java+String+Combine"));
System.out.println(combine("http://google.com/search", "/mail?inbox=Larry+Page"));
}

EditText validation not working as expected

I have developed android application and in there I have front end validation to a EditText field where its accept only three alpha and 4 digits.
It is tested in staging environment and front end validation is working perfectly (We don’t have back end validation). But after some time when we check
On our live database. We found some data with only digits relevant to above mentioned field. It seems somehow validation will not effect in some device
And we have received data with only digits. Is it possible or what can be the reason that we received invalid data.
// Check for id is valid format like "ABC1234".
String alphaLen = getResources().getString(R.string.rokaIdAlphaLen);
String numLen = getResources().getString(R.string.rokaIdNumericLen);
if (rokaId.length() > 0 && !Validate.validateRokaId(rokaId, alphaLen, numLen)) {
etRokaid.setError(getString(R.string.error_incorrect_format));
focusView = etRokaid;
cancel = true;
}
public static boolean validateRokaId(String params, String alphaLen, String numLen) {
boolean success = false;
int alphaLength = 0;
int numericLength = 0;
alphaLength = Integer.parseInt(alphaLen.trim());
numericLength = Integer.parseInt(numLen.trim());
if (params.length() == alphaLength + numericLength) {
if (params.substring(0, alphaLength).matches("[a-zA-Z]*")) {
if (params.substring(alphaLength, alphaLength+numericLength).matches("[0-9]*")) {
success = true;
} else {
success = false;
}
} else {
success = false;
}
} else {
success = false;
}
return success;
}
First of all you need to set Edit Text property android:digits in XML file for more security so no other special character to be inserted by the user even if you checked in validation.
android:digits="ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
Now for your format which is 3 character and 4 digit we create a Regex expression. You can create your own Regex Expression and test it from this site. I create this Regex from this site:
[A-Z]{3}\d{4}
public final static Pattern NAME_PATTERN = Pattern.compile("^[A-Z]{3}[0-9]{4}$");
Now just match this pattern.
if (NAME_PATTERN.matcher(edtText.getText().toString().trim()).matches())
{
// Write your logic if pattern match
}
else
{
// Write your logic if pattern not match
}

How to get URL from String on Android

I'd like to extract URL from hi there this is a URL String http://mytest.com.
I tried to use EditText.getURLs but it didn't work for me.
EditText.setText("hi there this is a URL String http://stackoverflow.com");
EditText.getURLs.toString();
How can I get URL from EditText?
Here is the function:
//Pull all links from the body for easy retrieval
private ArrayList pullLinks(String text) {
ArrayList links = new ArrayList();
String regex = "\\(?\\b(http://|www[.])[-A-Za-z0-9+&##/%?=~_()|!:,.;]*[-A-Za-z0-9+&##/%=~_()|]";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(text);
while(m.find()) {
String urlStr = m.group();
if (urlStr.startsWith("(") && urlStr.endsWith(")")) {
urlStr = urlStr.substring(1, urlStr.length() - 1);
}
links.add(urlStr);
}
return links;
}
change input type of your EditText ---- android:inputType="textUri"
and get your url using --- String url=edittext.getText().toString();
Check this library: (https://github.com/robinst/autolink-java)
compile "org.nibor.autolink:autolink:0.7.0"
Working fine with Android.
Example:
LinkExtractor linkExtractor = LinkExtractor.builder()
.linkTypes(EnumSet.of(LinkType.URL))
.build();
Iterable<LinkSpan> links = linkExtractor.extractLinks(String_with_Link");
LinkSpan link = links.iterator().next();
link.getType(); // LinkType.URL
link.getBeginIndex(); // 17
link.getEndIndex(); // 32
final_Url = String_with_Link.substring(link.getBeginIndex(), link.getEndIndex());

Java/Android regex test if in a string is a link

Pattern.compile("((http\\://|https\\://|ftp\\://|sftp\\://)|(www.))+((\\S+):(\\S+)#)?+(([a-zA-Z0-9\\.-]+\\.[a-zA-Z]{2,4})|([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}))(/[a-zA-Z0-9%:/-_\\?\\.'~]*)?");
I have this pattern, I'd like to test if there is a link in my string.
I'd like to linkify those text in a TextView.
The code does not work when the link contains a & character.
full code:
Pattern httpMatcher = Pattern.compile("((http\\://|https\\://|ftp\\://|sftp\\://)|(www.))+((\\S+):(\\S+)#)?+(([a-zA-Z0-9\\.-]+\\.[a-zA-Z]{2,4})|([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}))(/[a-zA-Z0-9%:/-_\\?\\.'~]*)?");
String httpViewURL = "myhttp://";
Linkify.addLinks(label, httpMatcher, httpViewURL);
I think this is cleaner that using regex:
boolean isLink(String s) {
try {
new URL(s);
return true;
} catch (MalformedURLException e) {
return false;
}
}
You can use Patterns.WEB_URL:
public boolean isLink(String string) {
return Patterns.WEB_URL.matcher(string).matches();
}
Note that Patterns class is available only since API level 8, but you can get its source code here https://github.com/android/platform_frameworks_base/blob/master/core/java/android/util/Patterns.java
Pattern httpMatcher = Pattern.compile("((http\\://|https\\://)|(www.))+((\\S+):(\\S+)#)?+(([a-zA-Z0-9\\.-]+\\.[a-zA-Z]{2,4})|([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}))(/[a-zA-Z0-9%&#-:/-_\\?\\.'~]*)?");
this is working now, thanks

Categories