Behavior of the function preg_match() for short names

Asked

Viewed 912 times

1

I set up a function that takes a full name with X names and surnames and returns only the first and last names. If you have a connective (from, from, from, dos, etc.) before the last surname, it attaches in the result.

But the function preg_match(), is returning the opposite expected by my regex.

Example:

function abrevia($var) {
$nomes = explode(" ", $var);
$a = reset($nomes);
$c = end($nomes);
if (count($nomes) > 2) {
    $b = prev($nomes);
    if (preg_match('/^[^A-Z]*$/', $b{0})) {
        return implode(" ", array($a, $b, $c));
    }
}
return implode(" ", array($a, $c));
}

$a[1] = "João Testador dos Testes";
$a[2] = "João dos Testis Testando do Teste";
$a[3] = "João do Teste";

$b = array_map('abrevia', $a);

var_dump($b);

Returns:

array (size=3)
1 => string 'João dos Testes' (length=16)
2 => string 'João do Teste' (length=14)
3 => string 'João do Teste' (length=14)

Doubt:

This function below should not return false(0)?

$b = "da";
var_dump(preg_match('/^[^A-Z]*$/', $b{0})); //retorna 1

4 answers

2

Your question has been answered, but you are predicting that the data will always come formatted as you want, ie names and surnames with the first uppercase and connective in lowercase...

thus reducing the possibility of errors:

<?php
    function abrevia($var) {
    $nomes = explode(" ", $var);
    $a = reset($nomes);
    $c = end($nomes);
    if (count($nomes) > 2) {
        $b = prev($nomes);
        if (preg_match('/^[deaos]{2,3}$/i', $b)) {
            return implode(" ", array($a, $b, $c));
        }
    }
    return implode(" ", array($a, $c));
    }

    $a[] = "João Testador dos Testes";
    $a[] = "joão dos testis testando teste";
    $a[] = "João do Teste";
    $a[] = "João Testador Das Dores";
    $a[] = "João Testador de Melo";
    $a[] = "João Testador Da Silva";

    $b = array_map('abrevia', $a);

    var_dump($b);
?>

returns:

array(6) {
  [0]=>
  string(15) "João dos Testes"
  [1]=>
  string(10) "joão teste"
  [2]=>
  string(13) "João do Teste"
  [3]=>
  string(14) "João Das Dores"
  [4]=>
  string(12) "João de Melo"
  [5]=>
  string(13) "João Da Silva"
}
  • It is because it comes from an Active Directory, where data is standardized, there is no such possibility because it would break a registration rule.

1


$b = "da";
var_dump(preg_match('/^[^A-Z]*$/', $b{0}));

Your regex says, match at line start(^) something other than capital letters between A-Z([^A-Z]) followed by any character(*), when it’s past $b[0] preg_match() applies regex only on d already you are passing the string Dice, the return is 1 why the combination happened.

  • Got it, what’s the negation operator for bad letters? What do you define as "not", instead of "be"? The string index I applied because in my case, in my AD, the names of the contributors always use the connective with lowercase, but I didn’t understand why it got "not be" instead of "be" lowercase? I spent a long time breaking my head because it worked my script, but the other way around. rs

  • 1

    The ^ within a list[] denies what is in it. In that link has the complete list of metacharacters.

  • It’s now clear!

0

Try this.

/**
 * Abreviar Nome
 * @param String $string Name user
 * @return string
 */
function FirstAndLastName($string) {
    $nome = explode(" ", $string);
    $first = $nome[0];
    $last = end($nome);
    if (count($nome) == 1) {
        $result = $nome[0];
    } else {
        $result = $first . ' ' . $last;
    }

    return $result;
}
  • It does not work, it needs to show the connectives as João da Silva, its function would eliminate the "da". In this case, my function is correct, I had only one question regarding the return of preg_match().

0

do so

 $nome = 'JOAO DOS TESTES';
 $retira = array(' DE ', ' DOS ', ' E ', ' DO ', ' DA ', ' DAS ', ' DI ');
 $nomeLimpo = str_replace($retira, ' ', $nome);

Browser other questions tagged

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