Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

246
Views
¿Usar solo expresiones regulares para dividir una cadena en una 'tupla' de nombre de archivo y extensión?

Sé que hay formas más fáciles de obtener extensiones de archivo con JavaScript , pero en parte para practicar mis habilidades de expresiones regulares, quería probar y usar una expresión regular para dividir un nombre de archivo en dos cadenas, antes y después del punto final (carácter . ).

Esto es lo que tengo hasta ahora

 const myRegex = /^((?:[^.]+(?:\.)*)+?)(\w+)?$/ const [filename1, extension1] = 'foo.baz.bing.bong'.match(myRegex); // filename1 = 'foo.baz.bing.' // extension1 = 'bong' const [filename, extension] = 'one.two'.match(myRegex); // filename2 = 'one.' // extension2 = 'two' const [filename, extension] = 'noextension'.match(myRegex); // filename2 = 'noextension' // extension2 = ''

Intenté usar la anticipación negativa para decir 'solo coincide con un literal'. si es seguido por una palabra que termina en, así, cambiando (?:\.)* a (?:\.(?=\w+.))* :

/^((?:[^.]+(?:\.(?=(\w+\.))))*)(\w+)$/gm

Pero quiero excluir ese período final usando solo la expresión regular, y preferiblemente hacer que coincida 'sin extensión' en el grupo inicial, ¿cómo puedo hacer eso solo con la expresión regular?

Aquí está mi archivo borrador de expresiones regulares: https://regex101.com/r/RTPRNU/1

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

Para el primer grupo de captura, puede comenzar la coincidencia con 1 o más caracteres de palabras. Luego, opcionalmente, repite un . y de nuevo 1 o más caracteres de palabra.

Luego, puede usar un grupo opcional que no sea de captura que coincida con un archivo . y capturando 1 o más caracteres de palabras en el grupo 2.

Como el segundo grupo de no captura es opcional, la primera repetición debe ser voraz.

 ^(\w+(?:\.\w+)*?)(?:\.(\w+))?$

El patrón coincide

  • ^ Comienzo de cadena
  • ( Grupo de captura 1
    • \w+(?:\.\w+)*? Haga coincidir 1+ caracteres de palabra y, opcionalmente, repita . y 1+ caracteres de palabra
  • ) Cerrar grupo 1
  • (?: Grupo de no captura para emparejar como un todo
    • \.(\w+) Coincide con un . y captura 1+ caracteres de palabra en el grupo de captura 2
  • )? Cierre el grupo de no captura y hágalo opcional
  • $ Fin de la cadena

Demostración de expresiones regulares

 const regex = /^(\w+(?:\.\w+)*?)(?:\.(\w+))?$/; [ "foo.baz.bing.bong", "one.two", "noextension" ].forEach(s => { const m = s.match(regex); if (m) { console.log(m[1]); console.log(m[2]); console.log("----"); } });

Otra opción como @ Wiktor Stribiżew publicó en los comentarios, es usar un punto no codicioso para hacer coincidir cualquier carácter para el nombre del archivo:

 ^(.*?)(?:\.(\w+))?$

Demostración de expresiones regulares

about 4 years ago · Juan Pablo Isaza Report

0

Si realmente desea usar expresiones regulares, sugeriría usar dos expresiones regulares:

 // example with 'foo.baz.bing.bong' const firstString = /^.+(?=\.\w+)./g // match 'foo.baz.bing.' const secondString = /\w+$/g // match 'bong'

about 4 years ago · Juan Pablo Isaza Report

0

¿Qué tal algo más explícito y preciso sin mirar alrededor?

  1. variante de grupos con nombre ... /^(?<noextension>\w+)$|(?<filename>\w+(?:\.\w+)*)\.(?<extension>\w+)$/ (?<sin extensión>\w+)$|(?<nombre de archivo>\w+(?:\.\w+)*)\.(?<extensión>\w+)$/

  2. sin grupos con nombre ... /^(\w+)$|(\w+(?:\.\w+)*)\.(\w+)$/

Las dos variantes que se acaban de mostrar se pueden acortar a 2 grupos de captura en lugar de los 3 grupos de captura de la variante anterior, lo que en mi opinión hace que sea más fácil trabajar con la expresión regular a costa de ser menos legible...

  1. variante de grupos con nombre ... /(?<nombre de archivo>\w+(?:\.\w+)*?)(?:\.(? /(?<filename>\w+(?:\.\w+)*?)(?:\.(?<extension>\w+))?$/

  2. sin grupos con nombre ... /(\w+(?:\.\w+)*?)(?:\.(\w+))?$/

 const testData = [ 'foo.baz.bing.bong', 'one.two', 'noextension', ]; // https://regex101.com/r/RTPRNU/5 const regXTwoNamedFileNameCaptures = /(?<filename>\w+(?:\.\w+)*?)(?:\.(?<extension>\w+))?$/; // https://regex101.com/r/RTPRNU/4 const regXTwoFileNameCaptures = /(\w+(?:\.\w+)*?)(?:\.(\w+))?$/; // https://regex101.com/r/RTPRNU/3 const regXThreeNamedFileNameCaptures = /^(?<noextension>\w+)$|(?<filename>\w+(?:\.\w+)*)\.(?<extension>\w+)$/ // https://regex101.com/r/RTPRNU/3 const regXThreeFileNameCaptures = /^(\w+)$|(\w+(?:\.\w+)*)\.(\w+)$/ console.log( 'based on 2 named file name captures ...\n', testData, ' =>', testData.map(str => regXTwoNamedFileNameCaptures.exec(str)?.groups ?? {} ) ); console.log( 'based on 2 unnamed file name captures ...\n', testData, ' =>', testData.map(str => { const [ match, filename, extension, ] = str.match(regXTwoFileNameCaptures) ?? []; //] = regXTwoFileNameCaptures.exec(str) ?? []; return { filename, extension, } }) ); console.log( 'based on 3 named file name captures ...\n', testData, ' =>', testData.map(str => { const { filename = '', extension = '', noextension = '', } = regXThreeNamedFileNameCaptures.exec(str)?.groups ?? {}; return { filename: filename || noextension, extension, } }) ); console.log( 'based on 3 unnamed file name captures ...\n', testData, ' =>', testData.map(str => { const [ match, noextension = '', filename = '', extension = '', ] = str.match(regXThreeFileNameCaptures) ?? []; //] = regXThreeFileNameCaptures.exec(str) ?? []; return { filename: filename || noextension, extension, } }) );
 .as-console-wrapper { min-height: 100%!important; top: 0; }

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!