Почему это регулярное выражение javascript не работает?

#regex #angular #angular-reactive-forms #angular-validation

#javascript #регулярное выражение

Вопрос:

Я использую небольшой метод javascript, который получает список точек, и я должен прочитать эти точки, чтобы создать полигон на карте Google.

Я получаю эти точки в форме:

(широта, длина), (широта, длина), (широта, длина)

Итак, я выполнил следующее регулярное выражение:

 (s*([0-9.-] )s*,s([0-9.-] )s*)
  

Я протестировал его с помощью RegexPal и точных данных, которые я получаю:

 (25.774252, -80.190262),(18.466465, -66.118292),(32.321384, -64.75737),(25.774252, -80.190262)
  

и это работает, так почему, когда у меня есть этот код в моем javascript, я получаю null в результате?

 var polygons="(25.774252, -80.190262),(18.466465, -66.118292),(32.321384, -64.75737),(25.774252, -80.190262)";
var reg = new RegExp("/(s*([0-9.-] )s*,s([0-9.-] )s*)/g");
var result = polygons.match(reg);
  

У меня нет ошибки javascript при выполнении (в режиме отладки Google Chrome). Этот код размещен в функции javascript, которая находится во включенном файле JS. Этот метод вызывается в методе OnLoad.

Я много искал, но не могу найти, почему это не работает. Большое вам спасибо!

Ответ №1:

Используйте литерал регулярного выражения [MDN]:

 var reg = /(s*([0-9.-] )s*,s([0-9.-] )s*)/g;
  

Вы допускаете две ошибки при использовании RegExp [MDN]:

  • «Разделители» / не должны быть частью выражения
  • Если вы определяете выражение как строку, вам нужно экранировать обратную косую черту, потому что это escape-символ в строках

Кроме того, модификаторы передаются в качестве второго аргумента функции.

Итак, если вы хотите использовать RegExp (что в данном случае необязательно), эквивалентом будет:

 var reg = new RegExp("\(\s*([0-9.-] )\s*,\s([0-9.-] )\s*\)", "g");
  

(и я думаю, теперь вы понимаете, почему литералы регулярных выражений более удобны)


Я всегда считаю полезным скопировать RegExp выражение в консоль и просмотреть его вывод. Принимая ваше исходное выражение, мы получаем:

 /(s*([0-9.-] )s*,s([0-9.-] )s*)/g
  

это означает, что выражения пытаются соответствовать / , s и g буквально, а скобки () по-прежнему обрабатываются как специальные символы.


Обновление: .match() возвращает массив:

 ["(25.774252, -80.190262)", "(18.466465, -66.118292)", ... ]
  

что, похоже, не очень полезно.

Вы должны использовать .exec() [MDN] для извлечения чисел:

 ["(25.774252, -80.190262)", "25.774252", "-80.190262"]
  

Это должно вызываться повторно, пока не будут обработаны все строки.

Пример:

 var reg = /(s*([0-9.-] )s*,s([0-9.-] )s*)/g;
var result, points = [];

while((result = reg.exec(polygons)) !== null) {
    points.push([ result[1],  result[2]]);
}
  

Это создает массив массивов, а унарный плюс ( ) преобразует строки в числа:

 [
    [25.774252, -80.190262], 
    [18.466465, -66.118292], 
    ...
]
  

Конечно, если вам нужны значения в виде строк, а не чисел, вы можете просто опустить .

Комментарии:

1. Отлично, это сработало! Я не знал этого synthax. Небольшой вопрос: я получаю массив с результатом, но как я могу получить содержимое моего захвата «(…)»? (это: ([0-9.-] ) )

2. Я допустил ошибку, вы должны сохранить g модификатор. Вам просто нужно использовать exec . Пожалуйста, ознакомьтесь с исправленной версией.

3. Хотя это довольно старый ответ, он помог мне завершить проверку формы. Лишний ‘ ‘ в ‘ .’ сделал это в конце 🙂