Все, что вам нужно, - перенаправить пользователя на какой-то URL выхода и вернуть на него ошибку 401 Unauthorized
. На странице ошибок (которая должна быть доступна без базового auth) вам необходимо предоставить полную ссылку на вашу домашнюю страницу (включая схему и имя хоста).
Пример для Nginx:
location /logout {
return 401;
}
error_page 401 /errors/401.html;
location /errors {
auth_basic off;
ssi on;
ssi_types text/html;
alias /home/user/errors;
}
Страница ошибки /home/user/errors/401.html
:
<!DOCTYPE html>
<p>You're not authorised. <a href="<!--# echo var="scheme" -->://<!--# echo var="host" -->/">Login</a>.</p>
Доступ к группам захвата можно получить следующим образом:
var myString = "something format_abc";
var myRegexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
var match = myRegexp.exec(myString);
console.log(match[1]); // abc
И если есть несколько совпадений, вы можете перебирать их:
var myString = "something format_abc";
var myRegexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
match = myRegexp.exec(myString);
while (match != null) {
// matched text: match[0]
// match start: match.index
// capturing group n: match[n]
console.log(match[0])
match = myRegexp.exec(myString);
}
Что касается приведенных выше примеров круглых скобок с несколькими совпадениями, я искал ответ здесь, не получив того, что хотел:
var matches = mystring.match(/(?:neededToMatchButNotWantedInResult)(matchWanted)/igm);
После просмотра немного запутанных вызовов функций с while и .push () выше, мне стало ясно, что проблема может быть решена очень элегантно с помощью mystring.replace () вместо этого (замена не является точкой и даже не выполнена, функция CLEAN, встроенная функция рекурсивной функции для второго параметра есть!):
var yourstring = 'something format_abc something format_def something format_ghi';
var matches = [];
yourstring.replace(/format_([^\s]+)/igm, function(m, p1){ matches.push(p1); } );
После этого я не думаю, что когда-либо буду использовать .match () для чего-то снова.
Нет необходимости ссылаться на метод exec
! Вы можете использовать метод «match» непосредственно в строке. Просто не забудьте скобки.
var str = "This is cool";
var matches = str.match(/(This is)( cool)$/);
console.log( JSON.stringify(matches) ); // will print ["This is cool","This is"," cool"] or something like that...
Позиция 0 имеет строку со всеми результатами. Позиция 1 имеет первое совпадение, представленное круглыми скобками, а позиция 2 имеет второе совпадение, выделенное в ваших круглых скобках. Вложенные круглые скобки сложны, поэтому будьте осторожны!
Вот метод, который вы можете использовать для получения группы захвата n th для каждого совпадения:
function getMatches(string, regex, index) {
index || (index = 1); // default to the first capturing group
var matches = [];
var match;
while (match = regex.exec(string)) {
matches.push(match[index]);
}
return matches;
}
// Example :
var myString = 'something format_abc something format_def something format_ghi';
var myRegEx = /(?:^|\s)format_(.*?)(?:\s|$)/g;
// Get an array containing the first capturing group for every match
var matches = getMatches(myString, myRegEx, 1);
// Log results
document.write(matches.length + ' matches found: ' + JSON.stringify(matches))
console.log(matches);
Ваш код работает для меня (FF3 на Mac), даже если я согласен с PhiLo , что регулярное выражение должно быть:
/\bformat_(.*?)\b/
(Но, конечно, я Я не уверен, потому что я не знаю контекста регулярного выражения.)
someString.match(regexPattern)
. /format_(.*?)/g
, где (.*?)
будет подобранной группой.) Они находятся в согласованных шаблонах. To получить доступ к сопоставленным группам , в каждом из сопоставленных шаблонов вам нужна функция или что-то похожее на итерацию по совпадению . Есть несколько способов сделать это, как показывают многие другие ответы. Большинство других ответов используют цикл while для повторения всех сопоставленных шаблонов , но я думаю, что мы все знаем потенциальные опасности с этим подходом. Необходимо сопоставлять с new RegExp()
, а не только с самим шаблоном, который упоминается только в комментарии. Это связано с тем, что метод .exec()
ведет себя аналогично функции генератора - , он останавливается каждый раз, когда имеется совпадение , но сохраняет его .lastIndex
, чтобы продолжить оттуда следующий .exec()
вызов.
Ниже приведен пример функции searchString
, которая возвращает Array
всех совпадающих паттернов , где каждый match
является Array
со всеми содержащими сопоставленными группами . Вместо использования цикла while я предоставил примеры, используя как функцию Array.prototype.map()
, так и более эффективный способ - используя простой for
-loop.
Они менее эффективны, поскольку они в основном реализуют forEach
-loop вместо более быстрого for
-loop.
// Concise ES6/ES2015 syntax
const searchString =
(string, pattern) =>
string
.match(new RegExp(pattern.source, pattern.flags))
.map(match =>
new RegExp(pattern.source, pattern.flags)
.exec(match));
// Or if you will, with ES5 syntax
function searchString(string, pattern) {
return string
.match(new RegExp(pattern.source, pattern.flags))
.map(match =>
new RegExp(pattern.source, pattern.flags)
.exec(match));
}
let string = "something format_abc",
pattern = /(?:^|\s)format_(.*?)(?:\s|$)/;
let result = searchString(string, pattern);
// [[" format_abc", "abc"], null]
// The trailing `null` disappears if you add the `global` flag
// Performant ES6/ES2015 syntax
const searchString = (string, pattern) => {
let result = [];
const matches = string.match(new RegExp(pattern.source, pattern.flags));
for (let i = 0; i < matches.length; i++) {
result.push(new RegExp(pattern.source, pattern.flags).exec(matches[i]));
}
return result;
};
// Same thing, but with ES5 syntax
function searchString(string, pattern) {
var result = [];
var matches = string.match(new RegExp(pattern.source, pattern.flags));
for (var i = 0; i < matches.length; i++) {
result.push(new RegExp(pattern.source, pattern.flags).exec(matches[i]));
}
return result;
}
let string = "something format_abc",
pattern = /(?:^|\s)format_(.*?)(?:\s|$)/;
let result = searchString(string, pattern);
// [[" format_abc", "abc"], null]
// The trailing `null` disappears if you add the `global` flag
Мне еще предстоит сравнить эти альтернативы с ранее упомянутыми в других ответах, но я сомневаюсь, что этот подход менее эффективен и менее безопасен, чем другие.
Используя ваш код:
console.log(arr[1]); // prints: abc
console.log(arr[0]); // prints: format_abc
Редактирование: Safari 3, если это имеет значение.
Ваш синтаксис, вероятно, не лучший. FF / Gecko определяет RegExp как расширение функции. (FF2 дошел до typeof(/pattern/) == 'function'
)
Кажется, это специфично для FF-IE, Opera и Chrome, все исключения для него исключают.
Вместо этого используйте любой метод ранее упомянутые другими: RegExp#exec
или String#match
. Они дают одинаковые результаты:
var regex = /(?:^|\s)format_(.*?)(?:\s|$)/;
var input = "something format_abc";
regex(input); //=> [" format_abc", "abc"]
regex.exec(input); //=> [" format_abc", "abc"]
input.match(regex); //=> [" format_abc", "abc"]
var myString = "something format_abc";
var arr = myString.match(/\bformat_(.*?)\b/);
console.log(arr[0] + " " + arr[1]);
\b
не совсем то же самое. (Он работает на --format_foo/
, но не работает на format_a_b
). Но я хотел показать альтернативу вашему выражению, что хорошо. Конечно, вызов match
- важная вещь.
format_a_b
». как после мысли 6 лет назад, и я не помню, что я имел в виду там ... :-) Я полагаю, это означало «не работает, чтобы захватить a
только», т.е. первая алфавитная часть после format_
.
– PhiLho
23 April 2015 в 07:41
Один вкладыш, который практичен, только если у вас есть одна пара скобок:
while ( ( match = myRegex.exec( myStr ) ) && matches.push( match[1] ) ) {};
function getMatches(string, regex, index) {
index || (index = 1); // default to the first capturing group
var matches = [];
var match;
while (match = regex.exec(string)) {
matches.push(match[index]);
}
return matches;
}
// Example :
var myString = 'Rs.200 is Debited to A/c ...2031 on 02-12-14 20:05:49 (Clear Bal Rs.66248.77) AT ATM. TollFree 1800223344 18001024455 (6am-10pm)';
var myRegEx = /clear bal.+?(\d+\.?\d{2})/gi;
// Get an array containing the first capturing group for every match
var matches = getMatches(myString, myRegEx, 1);
// Log results
document.write(matches.length + ' matches found: ' + JSON.stringify(matches))
console.log(matches);
function getMatches(string, regex, index) {
index || (index = 1); // default to the first capturing group
var matches = [];
var match;
while (match = regex.exec(string)) {
matches.push(match[index]);
}
return matches;
}
// Example :
var myString = 'something format_abc something format_def something format_ghi';
var myRegEx = /(?:^|\s)format_(.*?)(?:\s|$)/g;
// Get an array containing the first capturing group for every match
var matches = getMatches(myString, myRegEx, 1);
// Log results
document.write(matches.length + ' matches found: ' + JSON.stringify(matches))
console.log(matches);
/*Regex function for extracting object from "window.location.search" string.
*/
var search = "?a=3&b=4&c=7"; // Example search string
var getSearchObj = function (searchString) {
var match, key, value, obj = {};
var pattern = /(\w+)=(\w+)/g;
var search = searchString.substr(1); // Remove '?'
while (match = pattern.exec(search)) {
obj[match[0].split('=')[0]] = match[0].split('=')[1];
}
return obj;
};
console.log(getSearchObj(search));
И последнее, но не менее важное: я обнаружил, что один строчный код, который отлично работал для меня (JS ES6):
var reg = /#([\S]+)/igm; //get hashtags
var string = 'mi alegría es total! ✌
var match = myString.match(myRegexp); // alert(match[1])
? – JohnAllen 30 December 2013 в 19:39string = string.substring(match.index + match[0].length)
– Olga 11 February 2016 в 12:28