Skip to content

7. Expresiones regulares

Image

7.1. script [regex-01]

En el curso de PHP, utilizamos el siguiente código para ilustrar las expresiones regulares de PHP 7:


1. <?php
2. 
3. // strict type for function parameters
4. declare (strict_types=1);
5. 
6. // regular expressions in PHP
7. // extract the different fields from a string
8. // the pattern: a sequence of digits surrounded by any characters
9. // we only want to extract the sequence of digits
10. $pattern = "/(\d+)/";
11. // compare the string to the pattern
12. comparePatternToString($pattern, "xyz1234abcd");
13. comparePatternToString($pattern, "12 34");
14. comparePatternToString($pattern, "abcd");
15. 
16. // the pattern: a sequence of digits surrounded by any characters
17. // We want the sequence of digits as well as the fields that follow and precede it
18. $pattern = "/^(.*?)(\d+)(.*?)$/";
19. // we match the string against the pattern
20. comparePattern2String($pattern, "xyz1234abcd");
21. comparePattern2String($pattern, "12 34");
22. comparePatternToString($pattern, "abcd");
23. 
24. // the pattern - a date in dd/mm/yy format
25. $pattern = "/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/";
26. comparePattern2String($pattern, "10/05/97");
27. comparePattern2String($pattern, "  04/04/01  ");
28. compareTemplate2String($template, "5/1/01");
29. 
30. // the pattern - a decimal number
31. $pattern = "/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/";
32. comparePattern2String($pattern, "187.8");
33. comparePattern2String($pattern, "-0.6");
34. comparePattern2String($pattern, "4");
35. comparePattern2String($pattern, ".6");
36. comparePattern2String($pattern, "4.");
37. compareModel2String($model, " + 4");
38. 
39. // end
40. exit;
41. 
42. // --------------------------------------------------------------------------
43. function compareTemplateToString(string $template, string $string): void {
44.   // compares the string $string to the pattern $pattern
45.   // compare the string to the pattern
46.   $fields = [];
47.   $match = preg_match($pattern, $string, $fields);
48.   // display results
49.   print "\nResults($pattern,$string)\n";
50.   if ($match) {
51.     for ($i = 0; $i < count($fields); $i++) {
52.       print "fields[$i]=$fields[$i]\n";
53.     }
54.   } else {
55.     print "The string [$string] does not match the pattern [$pattern]\n";
56.   }
57. }

Convertimos este código a JavaScript de la siguiente manera:


1. 'use strict';
2. 
3. /// Regular expressions in JavaScript
4. // extract the different fields from a string
5. // the pattern: a sequence of digits surrounded by any characters
6. // we only want to extract the sequence of digits
7. let pattern = /(\d+)/;
8. // compare the string to the pattern
9. comparePatternToString(pattern, "xyz1234abcd");
10. comparePatternToString(pattern, "12 34");
11. comparePatternToString(pattern, "abcd");
12. 
13. // the pattern: a sequence of digits surrounded by any characters
14. // We want the sequence of digits as well as the fields that come before and after it
15. pattern = /^(.*?)(\d+)(.*?)$/;
16. // we match the string against the pattern
17. comparePatternToString(pattern, "xyz1234abcd");
18. comparePatternToString(pattern, "12 34");
19. comparePatternToString(pattern, "abcd");
20. 
21. // the pattern - a date in dd/mm/yy format
22. pattern = /^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/;
23. comparePatternToString(pattern, "10/05/97");
24. comparePatternToString(pattern, "  04/04/01  ");
25. comparePatternToString(pattern, "5/1/01");
26. 
27. // the pattern - a decimal number
28. pattern = /^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$/;
29. comparePatternToString(pattern, "187.8");
30. comparePatternToString(pattern, "-0.6");
31. comparePatternToString(pattern, "4");
32. comparePatternToString(pattern, ".6");
33. comparePatternToString(pattern, "4.");
34. compareModelToString(model, " + 4");
35. 
36. // --------------------------------------------------------------------------
37. function comparePatternToString(pattern, string) {
38.   // compares the string [string] to the pattern [pattern]
39.   console.log(`----------- string=${string}, pattern=${pattern}`)
40.   // compare the string to the pattern
41.   const result1 = pattern.exec(string);
42.   console.log(`comparison with exec=`, result1);
43.   // another way to do it
44.   const result2 = string.match(pattern);
45.   console.log(`comparison with match=`, result2);
46. }

Comentarios

  • El código PHP y JavaScript son muy similares;
  • línea 7: Tenga en cuenta que en JavaScript, una expresión regular no es una cadena, sino un objeto. No ponga comillas ni apóstrofes alrededor de la expresión;
  • Líneas 41 y 44: Hay dos formas de conseguir el mismo resultado;

Ejecución


1. [Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\regexp\regexp-01.js"
2. type of a regular expression: object
3. ----------- string=xyz1234abcd, pattern=/(\d+)/
4. comparison with exec= [ '1234',
5. '1234',
6. index: 3,
7. input: 'xyz1234abcd',
8. groups: undefined ]
9. comparison with match= [ '1234',
10. '1234',
11. index: 3,
12. input: 'xyz1234abcd',
13. groups: undefined ]
14. ----------- string=12 34, pattern=/(\d+)/
15. Comparison with exec= [ '12', '12', index: 0, input: '12 34', groups: undefined ]
16. comparison with match= [ '12', '12', index: 0, input: '12 34', groups: undefined ]
17. ----------- string=abcd, pattern=/(\d+)/
18. comparison with exec= null
19. comparison with match= null
20. ----------- string=xyz1234abcd, pattern=/^(.*?)(\d+)(.*?)$/
21. comparison with exec= [ 'xyz1234abcd',
22. 'xyz',
23. '1234',
24. 'abcd',
25. index: 0,
26. input: 'xyz1234abcd',
27. groups: undefined ]
28. comparison with match= [ 'xyz1234abcd',
29. 'xyz',
30. '1234',
31. 'abcd',
32. index: 0,
33. input: 'xyz1234abcd',
34. groups: undefined ]
35. ----------- string=12 34, pattern=/^(.*?)(\d+)(.*?)$/
36. comparison with exec= [ '12 34',
37. '',
38. '12',
39. ' 34',
40. index: 0,
41. input: '12 34',
42. groups: undefined ]
43. comparison with match= [ '12 34',
44. '',
45. '12',
46. ' 34',
47. index: 0,
48. input: '12 34',
49. groups: undefined ]
50. ----------- string=abcd, pattern=/^(.*?)(\d+)(.*?)$/
51. comparison with exec=null
52. comparison with match=null
53. ----------- string=10/05/97, pattern=/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/
54. comparison with exec= [ '10/05/97',
55. '10',
56. '05',
57. '97',
58. index: 0,
59. input: '10/05/97',
60. groups: undefined ]
61. comparison with match= [ '10/05/97',
62. '10',
63. '05',
64. '97',
65. index: 0,
66. input: '10/05/97',
67. groups: undefined ]
68. ----------- string= 04/04/01 , pattern=/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/
69. comparison with exec= [ ' 04/04/01 ',
70. '04',
71. '04',
72. '01',
73. index: 0,
74. input: '04/04/01',
75. groups: undefined ]
76. comparison with match= [ ' 04/04/01 ',
77. '04',
78. '04',
79. '01',
80. index: 0,
81. input: '04/04/01',
82. groups: undefined ]
83. ----------- string=5/1/01, pattern=/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/
84. comparison with exec=null
85. comparison with match=null
86. ----------- string=187.8, pattern=/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$/
87. comparison with exec= [ '187.8',
88. '',
89. '187.8',
90. index: 0,
91. input: '187.8',
92. groups: undefined ]
93. comparison with match= [ '187.8',
94. '',
95. '187.8',
96. index: 0,
97. input: '187.8',
98. groups: undefined ]
99. ----------- string=-0.6, pattern=/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$/
100. comparison with exec= [ '-0.6', '-', '0.6', index: 0, input: '-0.6', groups: undefined ]
101. comparison with match= [ '-0.6', '-', '0.6', index: 0, input: '-0.6', groups: undefined ]
102. ----------- string=4, pattern=/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$/
103. comparison with exec= [ '4', '', '4', index: 0, input: '4', groups: undefined ]
104. comparison with match= [ '4', '', '4', index: 0, input: '4', groups: undefined ]
105. ----------- pattern=.6, regex=/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$/
106. comparison with exec= [ '.6', '', '.6', index: 0, input: '.6', groups: undefined ]
107. comparison with match= [ '.6', '', '.6', index: 0, input: '.6', groups: undefined ]
108. ----------- string=4., pattern=/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$/
109. comparison with exec= [ '4.', '', '4.', index: 0, input: '4.', groups: undefined ]
110. comparison with match= [ '4.', '', '4.', index: 0, input: '4.', groups: undefined ]
111. ----------- string= + 4, pattern=/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$/
112. comparison with exec= [ ' + 4', '+', '4', index: 0, input: ' + 4', groups: undefined ]
113. comparison with match= [ ' + 4', '+', '4', index: 0, input: ' + 4', groups: undefined ]

Los [regexp.exec] y [string.match] métodos devuelven los mismos resultados:

  • [null] si no hay coincidencias entre la cadena y su patrón;
  • una matriz t, si hay una coincidencia con:
    • t[0]: la cadena que coincide con el patrón;
    • t[1]: la cadena que coincide con el primer paréntesis del patrón;
    • t[2]: la cadena que coincide con el segundo paréntesis del patrón;
    • ...
    • t[input]: la cadena completa en la que se ha buscado el patrón;

7.2. script [regexp-02]

A veces no quieres extraer elementos de la cadena probada, sino que sólo quieres saber si coincide con el patrón:


1. 'use strict';
2. 
3. /// regular expressions in JavaScript
4. // extract the different fields from a string
5. // the pattern: a sequence of digits surrounded by any characters
6. // we only want to extract the sequence of digits
7. let pattern = /\d+/;
8. console.log("Type of a regular expression: ", typeof (pattern));
9. // compare the string to the pattern
10. comparePatternToString(pattern, "xyz1234abcd");
11. comparePatternToString(pattern, "12 34");
12. comparePatternToString(pattern, "abcd");
13. 
14. // the pattern: a sequence of digits surrounded by arbitrary characters
15. // We want the sequence of digits as well as the fields that follow and precede it
16. pattern = /^.*?\d+.*?$/;
17. // we compare the string to the pattern
18. comparePatternToString(pattern, "xyz1234abcd");
19. comparePatternToString(pattern, "12 34");
20. comparePatternToString(pattern, "abcd");
21. 
22. // the pattern - a date in dd/mm/yy format
23. pattern = /^\s*\d\d\/\d\d\/\d\d\s*$/;
24. comparePatternToString(pattern, "10/05/97");
25. comparePatternToString(pattern, "  04/04/01  ");
26. comparePatternToString(pattern, "5/1/01");
27. 
28. // the pattern - a decimal number
29. pattern = /^\s*[+|-]?\s*\d+\.\d*|\.\d+|\d+\s*$/;
30. comparePatternToString(pattern, "187.8");
31. compareModelToString(model, "-0.6");
32. compareModelToString(model, "4");
33. compareModelToString(model, ".6");
34. compareModelToString(model, "4.");
35. compareModelToString(model, " + 4");
36. 
37. // --------------------------------------------------------------------------
38. function comparePatternToString(pattern, string) {
39.   // test
40.   const matches = pattern.test(string);
41.   // compare the string [string] to the pattern [pattern]
42.   console.log(`----------- string=${string}, pattern=${pattern}, matches=${matches}`);
43. }

Comentarios

  • [regexp-02] utiliza el código de [regexp-01] con las siguientes diferencias:
    • no queremos extraer elementos de la cadena analizada. Por lo tanto, hemos eliminado los paréntesis de las expresiones regulares utilizadas;
    • Línea 40: Utilizamos el [Regexp.test] método para determinar si una cadena coincide con una expresión regular;

Los resultados de la ejecución son los siguientes:


1. [Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\cours\regexp\regexp-02.js"
2. regular expression type:  object
3. ----------- string=xyz1234abcd, pattern=/\d+/, match=true
4. ----------- string=12 34, pattern=/\d+/, match=true
5. ----------- string=abcd, pattern=/\d+/, match=false
6. ----------- string=xyz1234abcd, pattern=/^.*?\d+.*?$/, matches=true
7. ----------- string=12 34, pattern=/^.*?\d+.*?$/, matches=true
8. ----------- string=abcd, pattern=/^.*?\d+.*?$/, matches=false
9. ----------- string=10/05/97, pattern=/^\s*\d\d\/\d\d\/\d\d\s*$/, matches=true
10. ----------- string=  04/04/01  , pattern=/^\s*\d\d\/\d\d\/\d\d\s*$/, matches=true
11. ----------- string=5/1/01, pattern=/^\s*\d\d\/\d\d\/\d\d\s*$/, matches=false
12. ----------- string=187.8, pattern=/^\s*[+|-]?\s*\d+\.\d*|\.\d+|\d+\s*$/, matches=true
13. ----------- string=-0.6, pattern=/^\s*[+|-]?\s*\d+\.\d*|\.\d+|\d+\s*$/, matches=true
14. ----------- string=4, pattern=/^\s*[+|-]?\s*\d+\.\d*|\.\d+|\d+\s*$/, matches=true
15. ----------- string=.6, pattern=/^\s*[+|-]?\s*\d+\.\d*|\.\d+|\d+\s*$/, matches=true
16. ----------- string=4., pattern=/^\s*[+|-]?\s*\d+\.\d*|\.\d+|\d+\s*$/, matches=true
17. ----------- string= + 4, pattern=/^\s*[+|-]?\s*\d+\.\d*|\.\d+|\d+\s*$/, matches=true
18. 
19. [Done] exited with code=0 in 0.269 seconds