2012-05-16 2 views
1

Мои URLs будут выглядеть следующим образом:RegEx для извлечения параметров из URL-адреса хэш в JavaScript

http://example.com/whatever#page?x=1&locale=hu&y=2 
http://example.com/whatever#page?x=1&locale=hu 
http://example.com/whatever#page?locale=hu 
http://example.com/whatever#page?locale= 
http://example.com/whatever#page?x=1 
http://example.com/whatever#page 
http://example.com/whatever 

Я хотел бы получить параметр локали или пустую строку, если он не установлен.

Я пытаюсь что-то вроде:

locale = location.hash.replace(/.*(?:[?&]locale=([^&]*))?.*/, "$2"); 

Но моя проблема в том, что я не мог найти правильный RegExp, который работает во всех случаях (как, когда есть локаль = хэш и когда ISN» t)

ответ

15

Вот фрагмент кода, который будет извлекать его из хэша и избежать его в другом месте в URL:

function getLocaleFromHash(url) { 
    var match = url.match(/#.*[?&]locale=([^&]+)(&|$)/); 
    return(match ? match[1] : ""); 
} 

И, вы можете увидеть его работу на всех ваших тестов здесь: http://jsfiddle.net/jfriend00/p37Mx/


Если вы хотите, чтобы иметь возможность искать любой Парм в хэш, вы бы использовать это:

function getParmFromHash(url, parm) { 
    var re = new RegExp("#.*[?&]" + parm + "=([^&]+)(&|$)"); 
    var match = url.match(re); 
    return(match ? match[1] : ""); 
} 

Смотреть это работает здесь: http://jsfiddle.net/jfriend00/6kgUk/


Более общая функция, которая будет получать все параметры в URL будет выглядеть следующим образом. Для обычных URL-адресов, где хэш после запроса и параметры находятся в строке запроса, он будет выглядеть так. Это немного больше кода, потому что он делает больше. Он извлекает все параметры в объект, где вы можете посмотреть любой параметр, это ключ и URL декодирует их все тоже:

function getParmsFromURL(url) { 
    var parms = {}, pieces, parts, i; 
    var hash = url.lastIndexOf("#"); 
    if (hash !== -1) { 
     // remove hash value 
     url = url.slice(0, hash); 
    } 
    var question = url.lastIndexOf("?"); 
    if (question !== -1) { 
     url = url.slice(question + 1); 
     pieces = url.split("&"); 
     for (i = 0; i < pieces.length; i++) { 
      parts = pieces[i].split("="); 
      if (parts.length < 2) { 
       parts.push(""); 
      } 
      parms[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]); 
     } 
    } 
    return parms; 
} 

Для специальной версии, которая обрабатывает параметры в хэш-значение и после? в хэш-значения, как в вопросе Ор (который не является типичным случаем), можно было бы использовать это:

function getParmsFromURLHash(url) { 
    var parms = {}, pieces, parts, i; 
    var hash = url.lastIndexOf("#"); 
    if (hash !== -1) { 
     // isolate just the hash value 
     url = url.slice(hash + 1); 
    } 
    var question = url.indexOf("?"); 
    if (question !== -1) { 
     url = url.slice(question + 1); 
     pieces = url.split("&"); 
     for (i = 0; i < pieces.length; i++) { 
      parts = pieces[i].split("="); 
      if (parts.length < 2) { 
       parts.push(""); 
      } 
      parms[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]); 
     } 
    } 
    return parms; 
} 

Работа демо: http://jsfiddle.net/jfriend00/v8cd5/

И затем, если вы хотите местный вариант, вы «D просто сделать это:

var parms = getParmsFromURL(url); 
var locale = parms["locale"]; 
+0

Мне нравится этот, потому что он легко можно использовать повторно, передавая параметр, который я ищу для функции :) – Gavriel

+0

@Gavriel - я добавил более общую функцию, которая позволяет передавать не только URL-адрес, но и параметр вы ищете в нем. – jfriend00

+0

спасибо, я уже сделал это в одиночку :) Просто вернулся, чтобы опубликовать его, но он идентичен вашей второй функции. – Gavriel

2
locale = location.hash.match(/[?&]locale=([^&]*)?/); 
locale = (locale == null ? "" : locale[1] || ""); 

Будет делать трюк. Я не думаю, что нужны .*, потому что вы не указываете начало или конец строки. Я проверил это регулярное выражение на всех ваших примерах, и все они работали правильно :)

Редактировать: Извините, в некоторых случаях это было недействительным. В настоящее время она правильна во всех случаях.

0

Если вы действительно хотите сделать это в одном из регулярных выражений:

locale = location.hash.match(/([?&]locale=|^((?![?&]locale=).)+$)([^&]*)/)[3]; 

Он работает против всех ваших примеров, хотя я думаю, что это ужасно неэффективно.

Смежные вопросы