2008-10-02 19 views
54

Uso RegexBuddy mientras trabajo con expresiones regulares. De su biblioteca copié la expresión regular para que coincida con las URL. Probé con éxito dentro de RegexBuddy. Sin embargo, cuando lo copié como Java String sabor y lo pegué en código Java, no funciona. Las impresiones de clase siguientes: falseExpresión regular para hacer coincidir las URL en Java

public class RegexFoo { 

    public static void main(String[] args) { 
     String regex = "\\b(https?|ftp|file)://[-A-Z0-9+&@#/%?=~_|!:,.;]*[-A-Z0-9+&@#/%=~_|]"; 
     String text = "http://google.com"; 
     System.out.println(IsMatch(text,regex)); 
} 

    private static boolean IsMatch(String s, String pattern) { 
     try { 
      Pattern patt = Pattern.compile(pattern); 
      Matcher matcher = patt.matcher(s); 
      return matcher.matches(); 
     } catch (RuntimeException e) { 
     return false; 
    }  
} 
} 

¿Alguien sabe lo que estoy haciendo mal?

+3

Sergio, no cogen RuntimeException. Puede presentar errores sutiles y es una mala práctica en general. Si solo quiere ignorar el escenario cuando la expresión es ilegal, use:} catch (PatternSyntaxException pse) {} en su lugar. Consulte el elemento 57 de: http://java.sun.com/docs/books/effective/ – OscarRyz

+0

O puede usar Pattern patt = Pattern.compile (pattern, Pattern.CASE_INSENSITIVE); para evitar cambiar la expresión regular para que coincida con letras mayúsculas y minúsculas. – jm4

+0

Sé que esto es realmente viejo ('08), pero para cualquier persona que tenga problemas similares, RegexBuddy tiene la pestaña "Usar". Asegúrese de seleccionar primero el sabor de Java 7 y luego, en el panel "Usar", puede dejar que genere el código de Java para su caso específico. Esto funcionó bien para mí. –

Respuesta

79

Pruebe la siguiente cadena de expresiones regulares en su lugar. Su prueba probablemente se hizo de una manera sensible a mayúsculas y minúsculas. He agregado las alfas minúsculas así como también un marcador de posición de comienzo de cadena apropiado.

String regex = "^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]"; 

Esto también funciona:

String regex = "\\b(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]"; 

Nota:

String regex = "<\\b(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]>"; // matches <http://google.com> 

String regex = "<^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]>"; // does not match <http://google.com> 
+0

Usando su expresión regular también obtengo falsa. –

+0

¿Has visto mi última edición? Estoy gordo tocando el comienzo de la cuerda. Acabo de copiarlo en Eclipse y me pongo "verdadero". – TomC

+1

gracias, primera vez que veo utilidad a los comentarios en stackoverflow –

56

Voy a tratar de una norma "¿Por qué haces de esta manera?" respuesta ... ¿Sabe usted acerca de java.net.URL?

URL url = new URL(stringURL); 

Lo anterior lanzará una MalformedURLException si no se puede analizar la URL.

+1

Tengo que pasar por el camino de expresiones regulares. Lo que publico aquí es lo más simple posible para aclarar mi pregunta. En mi programa, estoy usando la expresión regular de URL dentro de una expresión regular más compleja. –

+0

Eso es genial. No tuve una mejor respuesta regex-wise, así que pensé en publicar una alternativa. Sin embargo, no creí que me sentiría deprimido por ello. – billjamesdev

+2

tienes razón, tal vez un poco marcado fue un poco mucho. El "intentaré el estándar" sonaba un poco ofensivo. –

2

Esto funciona también:

String regex = "\\b(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]"; 

Nota:

String regex = "<\\b(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]>"; // matches <http://google.com> 

String regex = "<^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]>"; // does not match <http://google.com> 

Así que, probablemente, la primera de ellas es más útil para el uso general.

0

Al usar expresiones regulares de la biblioteca de RegexBuddy, asegúrese de usar los mismos modos de coincidencia en su propio código que la expresión regular de la biblioteca. Si genera un fragmento de código fuente en la pestaña Usar, RegexBuddy configurará automáticamente las opciones de coincidencia correctas en el fragmento de código fuente. Si copia/pega la expresión regular, debe hacerlo usted mismo.

En este caso, como señalaron otros, se perdió la opción de insensibilidad de mayúsculas y minúsculas.

3

El problema con todos los enfoques sugeridos: todo RegEx es validar

Todo expresiones regulares basadas en código es más de la ingeniería: se encontrará URL válidas sólo! Como muestra, ignorará cualquier cosa que comience con "http: //" y que contenga caracteres que no sean ASCII.

Aún más: He encontrado tiempos de procesamiento de 1-2 segundos (de un solo subproceso, dedicado) con el paquete Java RegEx (filtrado de direcciones de correo electrónico del texto) para oraciones muy pequeñas y sencillas, nada específico; posiblemente error en Java 6 RegEx ...

La solución más simple/rápida sería utilizar StringTokenizer para dividir texto en tokens, eliminar tokens que comiencen por "http: //" etc., y para concatenar tokens en texto de nuevo.

Si desea filtrar los correos electrónicos del texto (porque más adelante lo hará el personal de la PNL, etc.), simplemente elimine todos los tokens que contengan "@" en el interior.

Este es un texto simple donde falla el RegEx de Java 6. Pruébalo en las variantes divverent de Java. Se tarda unos 1.000 milisegundos por llamada RegEx, en una aplicación de prueba de un solo subproceso larga duración:

pattern = Pattern.compile("[A-Za-z0-9](([_\\.\\-]?[a-zA-Z0-9]+)*)@([A-Za-z0-9]+)(([\\.\\-]?[a-zA-Z0-9]+)*)\\.([A-Za-z]{2,})", Pattern.CASE_INSENSITIVE); 

"Avalanna is such a sweet little girl! It would b heartbreaking if cancer won. She's so precious! #BeliebersPrayForAvalanna"); 
"@AndySamuels31 Hahahahahahahahahhaha lol, you don't look like a girl hahahahhaahaha, you are... sexy."; 

No confíe en las expresiones regulares si sólo se necesita para filtrar las palabras con "@", "http: //", "ftp: //", "mailto:"; es una enorme sobrecarga de ingeniería.

Si realmente desea utilizar expresiones regulares con Java, intente Automaton

+0

Lol. Autómata no admite grupos de captura. – user1050755

+2

No me preocupo. La expresión regular de la respuesta aceptada de hecho funciona bien para validar las URL. Pareces ridiculizarlo, diciendo "¡encontrará solo URL válidas!", Ese es el objetivo de la pregunta de OP. ¿Me estoy perdiendo de algo? – mmcrae

71

La mejor manera de hacerlo ahora es:

android.util.Patterns.WEB_URL.matcher(linkUrl).matches(); 

EDIT: Código de Patterns de https://github.com/android/platform_frameworks_base/blob/master/core/java/android/util/Patterns.java:

/* 
* Copyright (C) 2007 The Android Open Source Project 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
*  http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
*/ 

package android.util; 

import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

/** 
* Commonly used regular expression patterns. 
*/ 
public class Patterns { 
    /** 
    * Regular expression to match all IANA top-level domains. 
    * List accurate as of 2011/07/18. List taken from: 
    * http://data.iana.org/TLD/tlds-alpha-by-domain.txt 
    * This pattern is auto-generated by frameworks/ex/common/tools/make-iana-tld-pattern.py 
    * 
    * @deprecated Due to the recent profileration of gTLDs, this API is 
    * expected to become out-of-date very quickly. Therefore it is now 
    * deprecated. 
    */ 
    @Deprecated 
    public static final String TOP_LEVEL_DOMAIN_STR = 
     "((aero|arpa|asia|a[cdefgilmnoqrstuwxz])" 
     + "|(biz|b[abdefghijmnorstvwyz])" 
     + "|(cat|com|coop|c[acdfghiklmnoruvxyz])" 
     + "|d[ejkmoz]" 
     + "|(edu|e[cegrstu])" 
     + "|f[ijkmor]" 
     + "|(gov|g[abdefghilmnpqrstuwy])" 
     + "|h[kmnrtu]" 
     + "|(info|int|i[delmnoqrst])" 
     + "|(jobs|j[emop])" 
     + "|k[eghimnprwyz]" 
     + "|l[abcikrstuvy]" 
     + "|(mil|mobi|museum|m[acdeghklmnopqrstuvwxyz])" 
     + "|(name|net|n[acefgilopruz])" 
     + "|(org|om)" 
     + "|(pro|p[aefghklmnrstwy])" 
     + "|qa" 
     + "|r[eosuw]" 
     + "|s[abcdeghijklmnortuvyz]" 
     + "|(tel|travel|t[cdfghjklmnoprtvwz])" 
     + "|u[agksyz]" 
     + "|v[aceginu]" 
     + "|w[fs]" 
     + "|(\u03b4\u03bf\u03ba\u03b9\u03bc\u03ae|\u0438\u0441\u043f\u044b\u0442\u0430\u043d\u0438\u0435|\u0440\u0444|\u0441\u0440\u0431|\u05d8\u05e2\u05e1\u05d8|\u0622\u0632\u0645\u0627\u06cc\u0634\u06cc|\u0625\u062e\u062a\u0628\u0627\u0631|\u0627\u0644\u0627\u0631\u062f\u0646|\u0627\u0644\u062c\u0632\u0627\u0626\u0631|\u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629|\u0627\u0644\u0645\u063a\u0631\u0628|\u0627\u0645\u0627\u0631\u0627\u062a|\u0628\u06be\u0627\u0631\u062a|\u062a\u0648\u0646\u0633|\u0633\u0648\u0631\u064a\u0629|\u0641\u0644\u0633\u0637\u064a\u0646|\u0642\u0637\u0631|\u0645\u0635\u0631|\u092a\u0930\u0940\u0915\u094d\u0937\u093e|\u092d\u093e\u0930\u0924|\u09ad\u09be\u09b0\u09a4|\u0a2d\u0a3e\u0a30\u0a24|\u0aad\u0abe\u0ab0\u0aa4|\u0b87\u0ba8\u0bcd\u0ba4\u0bbf\u0baf\u0bbe|\u0b87\u0bb2\u0b99\u0bcd\u0b95\u0bc8|\u0b9a\u0bbf\u0b99\u0bcd\u0b95\u0baa\u0bcd\u0baa\u0bc2\u0bb0\u0bcd|\u0baa\u0bb0\u0bbf\u0b9f\u0bcd\u0b9a\u0bc8|\u0c2d\u0c3e\u0c30\u0c24\u0c4d|\u0dbd\u0d82\u0d9a\u0dcf|\u0e44\u0e17\u0e22|\u30c6\u30b9\u30c8|\u4e2d\u56fd|\u4e2d\u570b|\u53f0\u6e7e|\u53f0\u7063|\u65b0\u52a0\u5761|\u6d4b\u8bd5|\u6e2c\u8a66|\u9999\u6e2f|\ud14c\uc2a4\ud2b8|\ud55c\uad6d|xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-3e0b707e|xn\\-\\-45brj9c|xn\\-\\-80akhbyknj4f|xn\\-\\-90a3ac|xn\\-\\-9t4b11yi5a|xn\\-\\-clchc0ea0b2g2a9gcd|xn\\-\\-deba0ad|xn\\-\\-fiqs8s|xn\\-\\-fiqz9s|xn\\-\\-fpcrj9c3d|xn\\-\\-fzc2c9e2c|xn\\-\\-g6w251d|xn\\-\\-gecrj9c|xn\\-\\-h2brj9c|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-j6w193g|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-kprw13d|xn\\-\\-kpry57d|xn\\-\\-lgbbat1ad8j|xn\\-\\-mgbaam7a8h|xn\\-\\-mgbayh7gpa|xn\\-\\-mgbbh1a71e|xn\\-\\-mgbc0a9azcg|xn\\-\\-mgberp4a5d4ar|xn\\-\\-o3cw4h|xn\\-\\-ogbpf8fl|xn\\-\\-p1ai|xn\\-\\-pgbs0dh|xn\\-\\-s9brj9c|xn\\-\\-wgbh1c|xn\\-\\-wgbl6a|xn\\-\\-xkc2al3hye2a|xn\\-\\-xkc2dl3a5ee0h|xn\\-\\-yfro4i67o|xn\\-\\-ygbi2ammx|xn\\-\\-zckzah|xxx)" 
     + "|y[et]" 
     + "|z[amw])"; 

    /** 
    * Regular expression pattern to match all IANA top-level domains. 
    * @deprecated This API is deprecated. See {@link #TOP_LEVEL_DOMAIN_STR}. 
    */ 
    @Deprecated 
    public static final Pattern TOP_LEVEL_DOMAIN = 
     Pattern.compile(TOP_LEVEL_DOMAIN_STR); 

    /** 
    * Regular expression to match all IANA top-level domains for WEB_URL. 
    * List accurate as of 2011/07/18. List taken from: 
    * http://data.iana.org/TLD/tlds-alpha-by-domain.txt 
    * This pattern is auto-generated by frameworks/ex/common/tools/make-iana-tld-pattern.py 
    * 
    * @deprecated This API is deprecated. See {@link #TOP_LEVEL_DOMAIN_STR}. 
    */ 
    @Deprecated 
    public static final String TOP_LEVEL_DOMAIN_STR_FOR_WEB_URL = 
     "(?:" 
     + "(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])" 
     + "|(?:biz|b[abdefghijmnorstvwyz])" 
     + "|(?:cat|com|coop|c[acdfghiklmnoruvxyz])" 
     + "|d[ejkmoz]" 
     + "|(?:edu|e[cegrstu])" 
     + "|f[ijkmor]" 
     + "|(?:gov|g[abdefghilmnpqrstuwy])" 
     + "|h[kmnrtu]" 
     + "|(?:info|int|i[delmnoqrst])" 
     + "|(?:jobs|j[emop])" 
     + "|k[eghimnprwyz]" 
     + "|l[abcikrstuvy]" 
     + "|(?:mil|mobi|museum|m[acdeghklmnopqrstuvwxyz])" 
     + "|(?:name|net|n[acefgilopruz])" 
     + "|(?:org|om)" 
     + "|(?:pro|p[aefghklmnrstwy])" 
     + "|qa" 
     + "|r[eosuw]" 
     + "|s[abcdeghijklmnortuvyz]" 
     + "|(?:tel|travel|t[cdfghjklmnoprtvwz])" 
     + "|u[agksyz]" 
     + "|v[aceginu]" 
     + "|w[fs]" 
     + "|(?:\u03b4\u03bf\u03ba\u03b9\u03bc\u03ae|\u0438\u0441\u043f\u044b\u0442\u0430\u043d\u0438\u0435|\u0440\u0444|\u0441\u0440\u0431|\u05d8\u05e2\u05e1\u05d8|\u0622\u0632\u0645\u0627\u06cc\u0634\u06cc|\u0625\u062e\u062a\u0628\u0627\u0631|\u0627\u0644\u0627\u0631\u062f\u0646|\u0627\u0644\u062c\u0632\u0627\u0626\u0631|\u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629|\u0627\u0644\u0645\u063a\u0631\u0628|\u0627\u0645\u0627\u0631\u0627\u062a|\u0628\u06be\u0627\u0631\u062a|\u062a\u0648\u0646\u0633|\u0633\u0648\u0631\u064a\u0629|\u0641\u0644\u0633\u0637\u064a\u0646|\u0642\u0637\u0631|\u0645\u0635\u0631|\u092a\u0930\u0940\u0915\u094d\u0937\u093e|\u092d\u093e\u0930\u0924|\u09ad\u09be\u09b0\u09a4|\u0a2d\u0a3e\u0a30\u0a24|\u0aad\u0abe\u0ab0\u0aa4|\u0b87\u0ba8\u0bcd\u0ba4\u0bbf\u0baf\u0bbe|\u0b87\u0bb2\u0b99\u0bcd\u0b95\u0bc8|\u0b9a\u0bbf\u0b99\u0bcd\u0b95\u0baa\u0bcd\u0baa\u0bc2\u0bb0\u0bcd|\u0baa\u0bb0\u0bbf\u0b9f\u0bcd\u0b9a\u0bc8|\u0c2d\u0c3e\u0c30\u0c24\u0c4d|\u0dbd\u0d82\u0d9a\u0dcf|\u0e44\u0e17\u0e22|\u30c6\u30b9\u30c8|\u4e2d\u56fd|\u4e2d\u570b|\u53f0\u6e7e|\u53f0\u7063|\u65b0\u52a0\u5761|\u6d4b\u8bd5|\u6e2c\u8a66|\u9999\u6e2f|\ud14c\uc2a4\ud2b8|\ud55c\uad6d|xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-3e0b707e|xn\\-\\-45brj9c|xn\\-\\-80akhbyknj4f|xn\\-\\-90a3ac|xn\\-\\-9t4b11yi5a|xn\\-\\-clchc0ea0b2g2a9gcd|xn\\-\\-deba0ad|xn\\-\\-fiqs8s|xn\\-\\-fiqz9s|xn\\-\\-fpcrj9c3d|xn\\-\\-fzc2c9e2c|xn\\-\\-g6w251d|xn\\-\\-gecrj9c|xn\\-\\-h2brj9c|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-j6w193g|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-kprw13d|xn\\-\\-kpry57d|xn\\-\\-lgbbat1ad8j|xn\\-\\-mgbaam7a8h|xn\\-\\-mgbayh7gpa|xn\\-\\-mgbbh1a71e|xn\\-\\-mgbc0a9azcg|xn\\-\\-mgberp4a5d4ar|xn\\-\\-o3cw4h|xn\\-\\-ogbpf8fl|xn\\-\\-p1ai|xn\\-\\-pgbs0dh|xn\\-\\-s9brj9c|xn\\-\\-wgbh1c|xn\\-\\-wgbl6a|xn\\-\\-xkc2al3hye2a|xn\\-\\-xkc2dl3a5ee0h|xn\\-\\-yfro4i67o|xn\\-\\-ygbi2ammx|xn\\-\\-zckzah|xxx)" 
     + "|y[et]" 
     + "|z[amw]))"; 

    /** 
    * Good characters for Internationalized Resource Identifiers (IRI). 
    * This comprises most common used Unicode characters allowed in IRI 
    * as detailed in RFC 3987. 
    * Specifically, those two byte Unicode characters are not included. 
    */ 
    public static final String GOOD_IRI_CHAR = 
     "a-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF"; 

    public static final Pattern IP_ADDRESS 
     = Pattern.compile(
      "((25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(25[0-5]|2[0-4]" 
      + "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]" 
      + "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}" 
      + "|[1-9][0-9]|[0-9]))"); 

    /** 
    * RFC 1035 Section 2.3.4 limits the labels to a maximum 63 octets. 
    */ 
    private static final String IRI 
     = "[" + GOOD_IRI_CHAR + "]([" + GOOD_IRI_CHAR + "\\-]{0,61}[" + GOOD_IRI_CHAR + "]){0,1}"; 

    private static final String GOOD_GTLD_CHAR = 
     "a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF"; 
    private static final String GTLD = "[" + GOOD_GTLD_CHAR + "]{2,63}"; 
    private static final String HOST_NAME = "(" + IRI + "\\.)+" + GTLD; 

    public static final Pattern DOMAIN_NAME 
     = Pattern.compile("(" + HOST_NAME + "|" + IP_ADDRESS + ")"); 

    /** 
    * Regular expression pattern to match most part of RFC 3987 
    * Internationalized URLs, aka IRIs. Commonly used Unicode characters are 
    * added. 
    */ 
    public static final Pattern WEB_URL = Pattern.compile(
     "((?:(http|https|Http|Https|rtsp|Rtsp):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)" 
     + "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_" 
     + "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?" 
     + "(?:" + DOMAIN_NAME + ")" 
     + "(?:\\:\\d{1,5})?)" // plus option port number 
     + "(\\/(?:(?:[" + GOOD_IRI_CHAR + "\\;\\/\\?\\:\\@\\&\\=\\#\\~" // plus option query params 
     + "\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])|(?:\\%[a-fA-F0-9]{2}))*)?" 
     + "(?:\\b|$)"); // and finally, a word boundary or end of 
         // input. This is to stop foo.sure from 
         // matching as foo.su 

    public static final Pattern EMAIL_ADDRESS 
     = Pattern.compile(
      "[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]{1,256}" + 
      "\\@" + 
      "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" + 
      "(" + 
       "\\." + 
       "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25}" + 
      ")+" 
     ); 

    /** 
    * This pattern is intended for searching for things that look like they 
    * might be phone numbers in arbitrary text, not for validating whether 
    * something is in fact a phone number. It will miss many things that 
    * are legitimate phone numbers. 
    * 
    * <p> The pattern matches the following: 
    * <ul> 
    * <li>Optionally, a + sign followed immediately by one or more digits. Spaces, dots, or dashes 
    * may follow. 
    * <li>Optionally, sets of digits in parentheses, separated by spaces, dots, or dashes. 
    * <li>A string starting and ending with a digit, containing digits, spaces, dots, and/or dashes. 
    * </ul> 
    */ 
    public static final Pattern PHONE 
     = Pattern.compile(      // sdd = space, dot, or dash 
       "(\\+[0-9]+[\\- \\.]*)?"  // +<digits><sdd>* 
       + "(\\([0-9]+\\)[\\- \\.]*)?" // (<digits>)<sdd>* 
       + "([0-9][0-9\\- \\.]+[0-9])"); // <digit><digit|sdd>+<digit> 

    /** 
    * Convenience method to take all of the non-null matching groups in a 
    * regex Matcher and return them as a concatenated string. 
    * 
    * @param matcher  The Matcher object from which grouped text will 
    *      be extracted 
    * 
    * @return    A String comprising all of the non-null matched 
    *      groups concatenated together 
    */ 
    public static final String concatGroups(Matcher matcher) { 
     StringBuilder b = new StringBuilder(); 
     final int numGroups = matcher.groupCount(); 

     for (int i = 1; i <= numGroups; i++) { 
      String s = matcher.group(i); 

      if (s != null) { 
       b.append(s); 
      } 
     } 

     return b.toString(); 
    } 

    /** 
    * Convenience method to return only the digits and plus signs 
    * in the matching string. 
    * 
    * @param matcher  The Matcher object from which digits and plus will 
    *      be extracted 
    * 
    * @return    A String comprising all of the digits and plus in 
    *      the match 
    */ 
    public static final String digitsAndPlusOnly(Matcher matcher) { 
     StringBuilder buffer = new StringBuilder(); 
     String matchingRegion = matcher.group(); 

     for (int i = 0, size = matchingRegion.length(); i < size; i++) { 
      char character = matchingRegion.charAt(i); 

      if (character == '+' || Character.isDigit(character)) { 
       buffer.append(character); 
      } 
     } 
     return buffer.toString(); 
    } 

    /** 
    * Do not create this static utility class. 
    */ 
    private Patterns() {} 
} 
+3

+1 para ti! ¡¡¡Muchas gracias!!! Este es un gran código! Todo el mundo está intentando esto con expresiones regulares difíciles, aunque podría ser así de fácil. ¡Increíble! –

+0

Esta debería ser la respuesta correcta – JPM

+6

@JPM Excepto que el OP estaba buscando una solución Java no específica de Android (es fácil olvidarse de ver las etiquetas específicas para una Q). Aún así, es bueno que los que codifican para Android lo supieran, así que aumenté. – indivisible

2

En línea con la respuesta de billjamesdev, este es otro enfoque para validar una URL sin usar un RegEx:

De Apache Commons Validator lib, mira la clase UrlValidator. Algunos ejemplos de código:

Construya un UrlValidator con esquemas válidos de "http" y "https".

String[] schemes = {"http","https"}. 
UrlValidator urlValidator = new UrlValidator(schemes); 
if (urlValidator.isValid("ftp://foo.bar.com/")) { 
    System.out.println("url is valid"); 
} else { 
    System.out.println("url is invalid"); 
} 

prints "url is invalid" 

Si, en cambio, se utiliza el constructor predeterminado.

UrlValidator urlValidator = new UrlValidator(); 
if (urlValidator.isValid("ftp://foo.bar.com/")) { 
    System.out.println("url is valid"); 
} else { 
    System.out.println("url is invalid"); 
} 

imprime "URL es válida"

Cuestiones relacionadas