¿Cómo puedo portar esta lógica de JavaScript como una expresión regular de una sola línea para usarla en PHP?

CorePress2024-01-25  250

Estoy intentando recrear las siguientes condiciones para validar la sintaxis de cadena en una única expresión regular para usar con PHP. ¿Cuál sería la expresión regular más rápida de usar y devolvería VERDADERO si se cumplen todas estas condiciones?

La cadena no debe estar vacía Longitud total de la cadena: >= 3 y <= 16 caracteres Caracteres permitidos en la cadena: a-z,0-9,-,. No se permiten letras mayúsculas El primer carácter debe ser una letra minúscula: a-z El último carácter debe ser una letra minúscula o un dígito: a-z o 0-9 No se pueden tener dos guiones consecutivos, en ninguna parte de la cadena.

Bonificación adicional: si es un punto/punto . existe, la cadena se segmenta usando el . como delimitador. Estos "segmentos" tiene reglas especiales:

Todas las reglas anteriores también se aplican a la cadena en su conjunto. El segmento debe comenzarcon una letra: a-z Final del segmento con una letra o un dígito: a-z 0-9 El segmento solo puede tener letras, dígitos o guiones: a-z 0-9 - El segmento debe ser => 3 caracteres de largo

Este "segmento" La lógica realmente me está desconcertando (sin juego de palabras). No estoy seguro de cómo incorporar todo junto.

Aquí hay un ejemplo de JavaScript que logra el objetivo. Estoy trabajando en PHP y necesito una expresión regular de una sola línea que valide VERDADERO si se cumplen todos los criterios. No necesito la lógica para explicar por qué falló (fuera de alcance). Solo necesito una expresión regular VERDADERO/FALSO. Dejo este fragmento por si le resulta útil:

export function validateAccountName(value) {
  let i, label, len, suffix;

  suffix = "Account name should ";
  if (!value) {
    return suffix + "not be empty.";
  }
  const length = value.length;
  if (length < 3) {
    return suffix + "be longer.";
  }
  if (length > 16) {
    return suffix + "be shorter.";
  }
  if (/\./.test(value)) {
    suffix = "Each account segment should ";
  }
  const ref = value.split(".");
  for (i = 0, len = ref.length; i < len; i++) {
    label = ref[i];
    if (!/^[a-z]/.test(label)) {
      return suffix + "start with a letter.";
    }
    if (!/^[a-z0-9-]*$/.test(label)) {
      return suffix + "have only letters, digits, or dashes.";
    }
    if (/--/.test(label)) {
      return suffix + "have only one dash in a row.";
    }
    if (!/[a-z0-9]$/.test(label)) {
      return suffix + "end with a letter or digit.";
    }
    if (!(label.length >= 3)) {
      return suffix + "be longer";
    }
  }
  return null;
}

¡Gracias!

Debes agregar algunas muestras válidas e inválidas

- anubhava

28 de marzo de 2021 a las 9:53

Mi opinión personal: si usted mismo no puede realizar una expresión regular de este tipo, probablemente tendrá dificultades para entenderla, modificarla más tarde y mantenerla. El código normal probablemente sería una mejor solución.

Software KIKO

28 de marzo de 2021 a las 9:54



------------------------------------

Puede utilizar una anticipación positiva para afirmar la longitud, incluidos el primer y el último carácter, y otra anticipación negativa para afirmar que no sean 2 guiones consecutivos.

^(?=[a-z][a-z\d.-]{1,14}[a-z\d]$)(?!.*--)[a-z\d-]+(?:\.[a-z][a-z\d-]+[a-z\d])*$

El patrón coincide

^ Inicio de la cadena (?=[a-z][a-z\d.-]{1,14}[a-z\d]$) Búsqueda positiva hacia adelante para afirmar de 3 a 16 caracteres, comenzando con a-z y terminando con a-z\d (?!.*--) Búsqueda anticipada negativa para afirmar no -- [a-z\d-]+ Coincide 1+ veces cualquiera de los caracteres enumerados (sin punto) (?: Grupo sin captura \.[a-z][a-z\d-]+[a-z\d] Coincide con un . y repita segmentos de al menos 3 caracteres comenzando con a-z, luego 1 o más veces cualquiera de los enumerados sin un punto y terminando en a-z\d sin el guión )* Cierre el grupo de no captura y, opcionalmente, repita $ Fin de cadena

Demostración de expresiones regulares

Si todas las piezas deben tener al menos 3 cHars cuando hay un punto presente, puedes repetir haciendo coincidir al menos 3 caracteres y acortar el patrón un poco repitiendo el primer grupo usando (?1) o ver el patrón sin el grupo.

^(?=[a-z][a-z\d.-]{1,14}[a-z\d]$)(?!.*--)([a-z][a-z\d-]+[a-z\d]+)(?:\.(?1))*$

Demostración de expresiones regulares

0



------------------------------------

También puedes probar esta expresión regular:

^[a-z](?!.*--)(?!.*\.([^.]{0,2}(\.|$)|[.\d-]))[a-z.\d-]{1,14}[a-z\d]$

Demostración de expresiones regulares

Explicación de expresiones regulares:

^: empezar [a-z]: Coincide con un carácter a-z (?!.*--): anticipación negativa para fallar la coincidencia si se encuentran 2 guiones consecutivos en cualquier lugar (?!.*\.([^.]{0,2}(\.|$)|[.\d-])): Búsqueda anticipada negativa para fallar la coincidencia si hay menos de 3 caracteres que no sean puntos después un punto o un carácter no alfar después del punto [a-z.\d-]{1,14}: haga coincidir de 1 a 14 instancias de a-z o un dígito o un dor o un carácter de guión [a-z\d]: Coincide con a-z o dígito $: Fin

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare