I implemented a generic function with some details (as in the case of the abbreviation of the last element of $list
- Soon you see that the abbreviation is not very beautiful, but playing a little with the code you improve it). The code is well commented, so I will not explain too much in text. Anything, ask in the comments.
The exit from the program:
$ ./abrev.php
26: Av. Natalino J. Brescansin
24: Joaquim Rossafa N. Filho
27: R. José Jesualdo G. Pessoa
36: Il. Sr. Dr. Jabulani J. Joniscleyson
16: Praça da Igreja
42: Pç. da Igreja N. S. M. d. J. C. N. Senhor
The code:
#!/usr/bin/php
<?php
/* tamanho máximo da string */
$max_length = 30;
$table = array(
"Avenida" => "Av.",
"Rua" => "R.",
"Praça" => "Pç.",
"Ilustríssimo" => "Il.",
"Senhor" => "Sr.",
"Senhora" => "Sra.",
"Doutor" => "Dr.");
$list = array(
"Avenida Natalino João Brescansin",
"Joaquim Rossafa Nascimento Filho",
"Rua José Jesualdo Garcia Pessoa",
"Ilustríssimo Senhor Doutor Jabulani Jurango Joniscleyson",
"Praça da Igreja",
"Praça da Igreja Nossa Senhora Mãe de Jesus Cristo Nosso Senhor");
/* MAIN: aqui é feita a abreviação dos itens */
foreach($list as &$str) {
if(strlen($str) >= $max_length)
abrev($str);
printf("%d: %s\n", strlen($str), $str);
}
/* &$str
*
* Significa que o parametro será uma referência, não um cópia. As alterações
* que eu fizer em $str dentro de abrev() são aplicadas à $str "verdadeira".
*/
function abrev(&$str)
{
/* referencias globais */
global $table;
global $max_length;
/* verifica entradas tabuladas,
*
* a contagem com preg_match é usada como offset no proximo
* loop.
*/
$matches = 0;
foreach($table as $k => $v) {
/* /$k/i
* testa a chave (as definições completas) na string.
* preg_replace funciona na mesma base.
*/
if(preg_match("/$k/i", $str)) {
$matches++;
$str = preg_replace("/$k/i", $v, $str, 1);
}
}
/* aqui separa-se a string em palavras */
$s = explode(" ", $str);
/* Rua José Jesualdo Garcia Pessoa
* pos : 0 1 2 3 4
*
* matches = 1
* count() = 5
*
* inicio
* i = 5 - 2 = 3 (começa no Garcia, penultimo nome)
*
* fim
* i >= $matches + 1 = 1 + 1 = 2
* (segunda palavra depois da ultima abreviação tabelada)
*/
for($i = count($s) - 2; $i >= $matches + 1; $i--) {
/* \.$ testa se o ultimo caractere da string é um ponto.
* Se for, significa que já está abreviado, e se já é uma
* palavra abreviada, saímos do loop.
*/
if(preg_match("/\.$/", $s[$i])) break;
/* unset é importante pra 'n' não ficar com lixo */
unset($n);
/* a primeira letra da palavra atual */
$n[] = $s[$i][0];
$n[] = ".";
/* substituimos s[i] pela versão abreviada */
$s[$i] = implode("", $n);
/* testa o tamanho total da string */
if(full_length($s) <= $max_length) break;
}
/* junta tudo pra "retornar"... o parâmetro é por referência,
* não por cópia
*/
$str = implode(" ", $s);
}
/* Nada elegante... *Nada* eficiente... mas quebra o galho.
*
* Provavelmente tem como fazer a troca de uma palavra por sua primeira letra
* seguida por um ponto usando expressões regulares.
*/
function full_length(array $s)
{
$s = implode(" ", $s);
return strlen($s);
}
?>
I’m usually against posting ready-made code, but since this is far from good for production... You’ll have to work on it to improve efficiency, especially if you’re going to use it on any engine data conversion.
Yes it is possible, since there is a rule or criterion, in cases of
rua
=>r
andavenida
=>av
is quiet and what is the rule for others?– rray
I thought about doing it this way, but I could not find enough rules or criteria to meet all the requirements. For example, in this situation I have addresses and names of people, we assume that we have the name 'Carlos Eduardo João Bruno Rodrigues', if the name 'João' is a middle name, it can be abbreviated, otherwise, no. Understands?
– Adriano de Azevedo
Words need to be abbreviated in such a way that they do not lose meaning.
– Adriano de Azevedo
interesting question, let’s go in parts: 1 - define the amount of words in the sentence; 2 - set the ideal length for the phrase; 3 - separate the phrase into words using split() or another procedure for that; 4 - with the word list of the phrase, vc can, in a loop, either search it for the largest after the first one or determine an index to determine which of the words that list abbreviate and pick the first letter of each word in that list and add ". " in them until the sentence reaches the desired size by what Oce determined as the ideal size;
– Armando Marques Sobrinho
I don’t remember almost anything about PHP, so I won’t even risk posting an answer. But basically you’ve had a lot of help. As the @rray colleague said, you need to set the rules. Some are obvious like the ones he mentions, others you need to create. For the atoms of the name, a possible rule to make the abbreviation could be: the name is short (less than x characters) and is not the first or the last. If you need abbreviate anyway, maybe the "name is short" part could be changed to "is the shortest of existing".
– Luiz Vieira
The @rray answer is correct, but care must be taken if a list of abbreviated words is created, note which street should be r. but raw is not abbreviated to cr. hug
– Aloiso Gomes
As already mentioned, you must first establish all the abbreviation rules. Done this post these rules in your question and people will be able to answer objectively.
– Joao Paulo