How to abbreviate words in PHP?

Asked

Viewed 1,970 times

10

I have common information like people names and addresses, and I need it to contain at most 30 characters without cutting words.

Example:

'Avenida Natalino João Brescansin' => 'Av. Natalino J. Brescansin'
'Joaquim Rossafa Nascimento filho' => 'Joaquim Rossafa N. filho'
'Rua José Jesualdo Garcia Pessoa'  => 'R. José Jesualdo G. Pessoa'

How can I do this in PHP?

Is there any method or regular expression to solve this problem?

  • 5

    Yes it is possible, since there is a rule or criterion, in cases of rua=>r and avenida=>av is quiet and what is the rule for others?

  • 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?

  • Words need to be abbreviated in such a way that they do not lose meaning.

  • 4

    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;

  • 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".

  • 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

  • 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.

Show 2 more comments

4 answers

6


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.

3

Come on, my dears,

when we abbreviate first names in PHP the task is simple, we must note that here in Brazil the names that must be kept in full if possible must be the first name and the last surname. Imagine the following name:

Antonio Fernades Coutinho

A pleasant result for the abbreviation of this case would be:

Antonio F. Coutinho

Omitting intermediate names can not always be seen with bad eyes:

Antonio Coutinho

But I will put below the solution that includes the first abbreviation that keeps only the initial of the abbreviated name followed by a point to indicate abbreviation.

//String com nome a ser abreviado
$name = "Antonio Fernandes Coutinho";

//como os nomes são separados por espaço em branco então vamos criar o array
//a partir dos espaços
$split_name = explode(" ",$name);


//so vamos abreviar o nome se 
//ele tiver pelo menos 2 sobrenomes
if(count($split_name) > 2){     

    //esse for inicia a partir da segunda
    // posição do array para o 
    //primeiro nome ser desconsiderado
    for($i=1;(count($split_name) - 1) > $i; $i++){

        //claro que como existem dos|de|da|das 
        //(Cristina DOS Santos) podemos 
        //omitir ou exibir sem abrevirar 
        //essas preposições, aqui no 
        //caso eu as mantenho sem alteração
        if(strlen($split_name[$i]) > 3){

            //aqui será feito a abreviação com apenas
            //a inicial da palavra a ser abreviada
            //seguida de ponto
            $split_name[$i] = substr($split_name[$i],0,1).".";  
        }       
    }   
}   

//aqui será impresso o nome resultante com a junção 
//do array em favor de se obter uma string colando as posições
//do array com espaços em branco!
echo implode(" ",$split_name);

// Antonio F. Coutinho

To abbreviate Street types (Street, Avenue, Square, ...) one can create an array with the gross values "Avenue" as key and "Av." as value of this key, and abbreviate when this is found in the string, with a slight change in the code above it is possible to do this.

It is clear that if the situation is more complex where you need to sanitize a high set of limited combinations consider using regular expression.

Hug

2

Plate, if you have a database with 20k of record, you create a Python Script that replaces the word if it exceeds 30 characters and then populate a table with id-based equivalence. Type, create a Dictionary ['Avenue':'Av', 'Street': 'R.', etc], then give a select * on the bench and itere with a loop for the returned list, throw an if no for that asks for the string Len and give the dictionary’s Replaces if you pass-if the 30 chars, create a basic dictionary and put to slice string with [0:x] if your dictionary does not do the full work. After you have the two tables in your database is teta link in php. Personally I don’t know anything more powerful to process String than Python.

0

In the case of people names, for example: Fulando de Tal, abbreviated by Fulando T., using a simple PHP script like this one below:

  $name = "Fulano de Tal";
  $array = array('da','de','di','do','du','das','des','dis','dos','dus','la','le','li','lo','lu','las','los','les');
  $n = explode(" ", $name);
  if (count($n) > 1) {
      $er = array_diff($n, $array);
      $eco = current($er);
      $eco2 = next($er);
      echo $eco;
      echo " ";
      echo substr($eco2,0,1).".";

  }else{
      echo $name;
  }

Browser other questions tagged

You are not signed in. Login or sign up in order to post.