0

Intento crear un Registro federal de contribuyente (RFC) de México con expresiones regulares en laravel y livewire pero me mada el siguiente error:

"preg_match(): No ending delimiter '/' found"

A continuacion mi codigo:

public function store(){
    $validatedDate = $this->validate([
        'nombre' => 'required',
        'rfc' => "required|regex:/^([A-Z]{3,4})(\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01]))([A-Z\d]{2}(?:[A\d]))?$/"
    ]);

    Supplier::create([
        'nombre' => $this->nombre,
        'rfc' => $this->rfc
    ]);           
}

Algo esta mal con la validacion del campo rfc, especificamente con el regex. Ayuda!

3 respuestas 3

1

Intenta de esta manera:

protected $rules = [
    'nombre' => 'required',
    'rfc' => ['required', 'regex:/^([A-Z]{3,4})(\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01]))([A-Z\d]{2}(?:[A\d]))?$/'],
];

ó:

$validatedDate = $this->validate([
    'nombre' => 'required',
    'rfc' => ['required', 'regex:/^([A-Z]{3,4})(\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01]))([A-Z\d]{2}(?:[A\d]))?$/'],
]);
0

No valides con regex, valida con el siguiente:

<?php

function validaRfc($rfc)
{
   $matrizValores = [
      "0" =>  0, "1" =>  1, "2" =>  2, "3" =>  3, "4" =>  4,
      "5" =>  5, "6" =>  6, "7" =>  7, "8" =>  8, "9" =>  9,
      "A" => 10, "B" => 11, "C" => 12, "D" => 13, "E" => 14,
      "F" => 15, "G" => 16, "H" => 17, "I" => 18, "J" => 19,
      "K" => 20, "L" => 21, "M" => 22, "N" => 23, "&" => 24,
      "O" => 25, "P" => 26, "Q" => 27, "R" => 28, "S" => 29,
      "T" => 30, "U" => 31, "V" => 32, "W" => 33, "X" => 34,
      "Y" => 35, "Z" => 36, " " => 37, "Ñ" => 38
   ];

   $rfc = str_split($rfc);

   //Eliminamos el último dígito, ya que el dígito se calcula en base a los doce primeros numeros.
   array_pop($rfc);

   //Los valores se asigan del 13-2, o lo mismo poner al revés y asignar del 2-13.
   $rfc = array_reverse($rfc);

   $suma = 0;
   $multiplicador = 2;
   foreach ($rfc as $caracter) {
      $suma += $matrizValores[$caracter] * $multiplicador;
      $multiplicador++;
   }

   $modulo11 = $suma % 11;
   $digito = 11 - $modulo11;

   // Si $digito es 11 se convierte a 0, Si es 10 el digito es "A"
   return $digito == 10 ? "A" : ($digito == 11 ? 0 : $digito);
}

echo validaRfc("PECO8902108P8");
1
  • Tal y como está redactada, tu respuesta no es clara. Por favor, pulsa en editar para añadir detalles adicionales que ayuden a los demás a entender cómo esto responde a la pregunta formulada. Puedes encontrar más información sobre cómo escribir buenas respuestas en el centro de ayuda.
    – Comunidad Bot
    Commented el 21 may. a las 19:38
0

No puedo comentar todavía por falta de reputación, pero lo que sugiere Gonzalo me parece bien. Según entiendo, primero validarías con una expresión regular solo para checar que cumpla en estructura. Después validarías que el último dígito que tiene el RFC coincida con el calculado por la función.

Lo que yo hice fue esto, tengo dos reglas básicas del RFC, luego una personalizada

'rfc' => ['required', 'string', new RfcRule]

Creé una clase ValidadorRfc con

php artisan make:class ValidadorRfc

Y ahí puse un método para validar con regex y otro para módulo 11

class ValidadorRfc
{
    /**
     * Valida un RFC usando una expresión regular.
     *
     * @param string $rfc
     * @return bool
     */
    public static function validarConRegex($rfc)
    {
        return preg_match('/[A-ZÑ&]{3,4}\d{6}[A-V1-9][A-Z1-9][0-9A]/', $rfc);
    }

    /**
     * Valida un RFC usando módulo 11.
     *
     * @param string $rfc
     * @return bool
     */
    public static function validarConModulo11($rfc)
    {
        $matrizValores = [
            "0" =>  0, "1" =>  1, "2" =>  2, "3" =>  3, "4" =>  4,
            "5" =>  5, "6" =>  6, "7" =>  7, "8" =>  8, "9" =>  9,
            "A" => 10, "B" => 11, "C" => 12, "D" => 13, "E" => 14,
            "F" => 15, "G" => 16, "H" => 17, "I" => 18, "J" => 19,
            "K" => 20, "L" => 21, "M" => 22, "N" => 23, "&" => 24,
            "O" => 25, "P" => 26, "Q" => 27, "R" => 28, "S" => 29,
            "T" => 30, "U" => 31, "V" => 32, "W" => 33, "X" => 34,
            "Y" => 35, "Z" => 36, " " => 37, "Ñ" => 38
        ];

        $rfc = str_split($rfc);

        //Eliminamos el último dígito, ya que el dígito se calcula en base a los doce primeros numeros.
        $ultimo_digito_actual = array_pop($rfc);

        //Los valores se asigan del 13-2, o lo mismo poner al revés y asignar del 2-13.
        $rfc = array_reverse($rfc);

        $suma = 0;
        $multiplicador = 2;

        foreach ($rfc as $caracter) {
            $suma += $matrizValores[$caracter] * $multiplicador;
            $multiplicador++;
        }

        $modulo11 = $suma % 11;
        $digito = 11 - $modulo11;

        // Si $digito es 11 se convierte a 0, Si es 10 el digito es "A"
        $ultimo_digito_real = $digito === 10 ? "A" : ($digito == 11 ? "0" : (string) $digito);

        return $ultimo_digito_actual === $ultimo_digito_real;
    }
}

Luego uso ambos en RfcRule, primero con la regex y luego con el módulo 11

class RfcRule implements ValidationRule
{
    /**
     * Run the validation rule.
     *
     * @param  \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString  $fail
     */
    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        if (!ValidadorRfc::validarConRegex($value)) {
            $fail("El RFC no es válido");
            return;
        }

        if (!ValidadorRfc::validarConModulo11($value)) {
            $fail("El RFC no es válido");
            return;
        }
    }
}

El return en cada if va porque $fail no hace que se salga de la función, entonces en muchos casos necesitas que las condiciones pues vayan en orden y es importante retornar la función.

1
  • Tal y como está redactada, tu respuesta no es clara. Por favor, pulsa en editar para añadir detalles adicionales que ayuden a los demás a entender cómo esto responde a la pregunta formulada. Puedes encontrar más información sobre cómo escribir buenas respuestas en el centro de ayuda.
    – Comunidad Bot
    Commented el 21 may. a las 19:38

¿No es la respuesta que buscas? Examina otras preguntas con la etiqueta o formula tu propia pregunta.