Quiero recuperar la oración completa que rodea un enlace, delimitada por puntuación (como . o ! o ? o salto de línea).
El propósito es proporcionar un mejor contexto para el enlace.
Entonces, por ejemplo, si tengo esto...
$input = "I don't want this piece! This is the <a href='https://example.com/my-sentence'>sentence</a> I want. In don't want this piece either"; $filter = "https://example.com/my-sentence";
... Necesito llegar a eso...
$output = "This is the sentence I want.";
Hasta ahora, logré aislar una oración que no contiene etiquetas, como esta:
$input = "I don't want this piece. This is the sentence I want. In don't want this piece either"; $filter = "sentence"; $regex = '/[AZ][^\\.;]*('.$filter.')[^\\.;]*/'; if (preg_match($regex, $input, $match)) $output = $match[0];
Esto funciona bien. A continuación, no sé cómo sortear la puntuación dentro de la URL.
Exploré el aislamiento del ancla primero y la expresión regular de eso, lo que funciona en cualquier ejemplo individual pero puede generar colisiones en la naturaleza (anclajes que duplican otras anclas o texto aleatorio).
Otra forma de hacerlo parece ser strip_tags, algo así como...
$input = strip_tags($input);
... el problema es que los necesito despojados y no despojados al mismo tiempo.
Tal vez una expresión regular más específica o un ajuste inteligente de las funciones podría brindar una salida fácil a esto, o tal vez es un callejón sin salida y se requiere algún otro enfoque, no lo sé, pero ahora mismo estoy atascado, por favor ayuda !
De acuerdo, no le importan las abreviaturas, puede hacer coincidir un carácter que no sea ?
, !
y .
, o una subcadena similar a un enlace cero o más veces antes y después de una cadena de filtro específica:
$input = "I don't want this piece! This is the <a href='https://example.com/my-sentence'>sentence</a> I want. In don't want this piece either"; $filter = "sentence"; $regex = '~\b(?:[^.?!]|https?://[^<>\s"\']++)*?'.preg_quote($filter, '~').'(?:[^.?!]|https?://[^<>\s"\']++)*~u'; if (preg_match_all($regex, $input, $match)){ print_r( array_map(function($x) {return strip_tags($x);}, $match[0]) ); }
Vea la demostración de PHP . Producción:
Array ( [0] => This is the sentence I want )
Vea la demostración de expresiones regulares . Detalles :
\b
- un límite de palabra(?:[^.?!]|https?://[^<>\s"\']++)*?
- cero o más apariciones, la menor cantidad posible, de un carácter que no sea .
, ?
y !
o http
, una s
, ://
opcional y luego uno o más caracteres que no sean <
, >
, espacio en blanco, "
, '
sentence
- una cadena de filtro(?:[^.?!]|https?://[^<>\s"\']++)*
- cero o más apariciones, tantas como sea posible, de un carácter que no sea .
, ?
y !
o http
, una s
opcional , ://
y luego uno o más caracteres que no sean <
, >
, espacio en blanco, "
, '