2012-01-23 11 views
8

Actualmente realizo la detección automática de hipervínculos dentro del texto en mi programa. Lo hice muy simple y solo busco http: // o www.Cómo puedo implementar un conjunto estándar de reglas de detección de hipervínculos en Delphi

Sin embargo, un usuario me sugirió que me extiendo a otras formas, por ejemplo: https: // o .com

Entonces me di cuenta de que tal vez no se detiene allí, porque hay ftp y mailto y archivo, todos los demás dominios de nivel superior e incluso direcciones de correo electrónico y rutas de archivos.

Lo que creo que es mejor es limitarlo a lo práctico siguiendo algunas reglas estándar de detección de hipervínculos que se utilizan a menudo. Tal vez cómo lo hace Microsoft Word, o tal vez cómo RichEdit lo hace o tal vez usted conozca un mejor estándar.

Así que mi pregunta es:

¿Existe una función integrada que puedo llamar desde Delphi para hacer la detección, y si es así, ¿cuál sería el aspecto de llamada como? (Planeo en el futuro ir a FireMonkey, entonces preferiría algo que funcione más allá de Windows.)

Si no hay una función disponible, ¿hay algún lugar donde pueda encontrar un conjunto documentado de reglas de qué se detecta en Word, en RichEdit o en cualquier otro conjunto de reglas de lo que se debe detectar? Eso me permitiría escribir el código de detección yo mismo.

+0

dudo mucho que hay un "estándar" por ahí, sólo "¿Qué hacer diversos productos de MS Office como Word, Excel y Outloo k hacer ". Dado que es de código abierto, si puede leer C++, me gustaría ver la funcionalidad en mozilla thunderbird. –

Respuesta

7

Pruebe la función PathIsURL que se declara en la unidad ShLwApi.

+0

Eso no hará todo el trabajo cuando la ruta esté incrustada en otro texto. –

+4

Esto no sería tan malo si reviso cada palabra (delimitada por espacios u otros caracteres que no sean URL) más larga que, digamos, 5 caracteres dentro de mi texto. – lkessler

1

Las expresiones regulares pueden ser el camino a seguir aquí, para definir los diversos patrones que considera apropiados hipervínculos.

+1

He visto varias implementaciones de expresiones regulares para hacer esto, pero ¿cómo puedo determinar cuáles son un "conjunto estándar"? Mi otra preocupación es qué tan eficientes son, ya que tengo grandes archivos para procesar. – lkessler

+0

Use expresiones regulares * especialmente * si le preocupa el rendimiento. El lenguaje RegEx puede expresar lo que está buscando muy bien, y el compilador RegEx lo convertirá en algo muy eficiente. Para expresiones complejas, es definitivamente más rápido y fácil de mantener que los analizadores codificados a mano. –

3

El siguiente regex tomado de la biblioteca de RegexBuddy podría comenzar (No puedo afirmar nada sobre el rendimiento).

Regex

Match; JGsoft; case insensitive: 
\b(https?|ftp|file)://[-A-Z0-9+&@#/%?=~_|$!:,.;]*[A-Z0-9+&@#/%=~_|$] 

Explicación

URL: Encontrar en texto completo La clase carácter final se asegura de que si una URL es parte de un texto, puntuacion como una coma o punto final después de que la URL no se interprete como parte de la URL.

Correspondencias (total o parcial)

http://regexbuddy.com 
http://www.regexbuddy.com 
http://www.regexbuddy.com/ 
http://www.regexbuddy.com/index.html 
http://www.regexbuddy.com/index.html?source=library 
You can download RegexBuddy at http://www.regexbuddy.com/download.html. 

No coincide con

regexbuddy.com 
www.regexbuddy.com 
"www.domain.com/quoted URL with spaces" 
[email protected] 

Para un conjunto de reglas se puede intentar RFC 3986

un identificador de recursos uniforme (URI) es una secuencia compacta de
caracteres que identifica un recurso abstracto o físico. Esta especificación
define la sintaxis genérica URI y un proceso para
resolver referencias URI que podrían estar en forma relativa, junto con
directrices y consideraciones de seguridad para el uso de URIs en la
Internet

A expresiones regulares que valida una dirección URL como se especifica en el RFC 3986 sería

^ 
(# Scheme 
[a-z][a-z0-9+\-.]*: 
(# Authority & path 
    // 
    ([a-z0-9\-._~%!$&'()*+,;=][email protected])?    # User 
    ([a-z0-9\-._~%]+       # Named host 
    |\[[a-f0-9:.]+\]       # IPv6 host 
    |\[v[a-f0-9][a-z0-9\-._~%!$&'()*+,;=:]+\]) # IPvFuture host 
    (:[0-9]+)?         # Port 
    (/[a-z0-9\-._~%!$&'()*+,;=:@]+)*/?   # Path 
|# Path without authority 
    (/?[a-z0-9\-._~%!$&'()*+,;=:@]+(/[a-z0-9\-._~%!$&'()*+,;=:@]+)*/?)? 
) 
|# Relative URL (no scheme or authority) 
([a-z0-9\-._~%!$&'()*+,;[email protected]]+(/[a-z0-9\-._~%!$&'()*+,;=:@]+)*/? # Relative path 
|(/[a-z0-9\-._~%!$&'()*+,;=:@]+)+/?)       # Absolute path 
) 
# Query 
(\?[a-z0-9\-._~%!$&'()*+,;=:@/?]*)? 
# Fragment 
(\#[a-z0-9\-._~%!$&'()*+,;=:@/?]*)? 
$ 
Cuestiones relacionadas