从查询字符串中删除一个参数的正则表达式 [英] Regular expression to remove one parameter from query string
问题描述
我正在寻找一个正则表达式来从查询字符串中删除单个参数,如果可能的话,我想在单个正则表达式中完成.
I'm looking for a regular expression to remove a single parameter from a query string, and I want to do it in a single regular expression if possible.
假设我想删除 foo
参数.现在我用这个:
Say I want to remove the foo
parameter. Right now I use this:
/&?foo\=[^&]+/
只要 foo
不是查询字符串中的第一个参数,它就可以工作.如果是,那么我的新查询字符串以与号开头.(例如,foo=123&bar=456
"给出&bar=456
"的结果.)现在,我只是在检查如果查询字符串以 & 开头,则使用正则表达式,如果是,则将其截断.
That works as long as foo
is not the first parameter in the query string. If it is, then my new query string starts with an ampersand. (For example, "foo=123&bar=456
" gives a result of "&bar=456
".) Right now, I'm just checking after the regex if the query string starts with ampersand, and chopping it off if it does.
边缘情况示例:
Input | Expected Output
-------------------------+--------------------
foo=123 | (empty string)
foo=123&bar=456 | bar=456
bar=456&foo=123 | bar=456
abc=789&foo=123&bar=456 | abc=789&bar=456
<小时>
编辑
好的,正如评论中指出的那样,边缘情况比我最初考虑的要多得多.我得到了以下正则表达式来处理所有这些:
Edit
OK as pointed out in comments there are there are way more edge cases than I originally considered. I got the following regex to work with all of them:
/&foo(\=[^&]*)?(?=&|$)|^foo(\=[^&]*)?(&|$)/
这是从 Mark Byers 的回答中修改的,这就是我接受那个的原因,但 Roger Pate 的意见也有很大帮助.
This is modified from Mark Byers's answer, which is why I'm accepting that one, but Roger Pate's input helped a lot too.
这是我正在使用的全套测试用例,以及测试它们的 Javascript 片段:
Here is the full suite of test cases I'm using, and a Javascript snippet which tests them:
$(function() {
var regex = /&foo(\=[^&]*)?(?=&|$)|^foo(\=[^&]*)?(&|$)/;
var escapeHtml = function (str) {
var map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
return str.replace(/[&<>"']/g, function(m) { return map[m]; });
};
//test cases
var tests = [
'foo' , 'foo&bar=456' , 'bar=456&foo' , 'abc=789&foo&bar=456'
,'foo=' , 'foo=&bar=456' , 'bar=456&foo=' , 'abc=789&foo=&bar=456'
,'foo=123' , 'foo=123&bar=456' , 'bar=456&foo=123' , 'abc=789&foo=123&bar=456'
,'xfoo' , 'xfoo&bar=456' , 'bar=456&xfoo' , 'abc=789&xfoo&bar=456'
,'xfoo=' , 'xfoo=&bar=456' , 'bar=456&xfoo=' , 'abc=789&xfoo=&bar=456'
,'xfoo=123', 'xfoo=123&bar=456', 'bar=456&xfoo=123', 'abc=789&xfoo=123&bar=456'
,'foox' , 'foox&bar=456' , 'bar=456&foox' , 'abc=789&foox&bar=456'
,'foox=' , 'foox=&bar=456' , 'bar=456&foox=' , 'abc=789&foox=&bar=456'
,'foox=123', 'foox=123&bar=456', 'bar=456&foox=123', 'abc=789&foox=123&bar=456'
];
//expected results
var expected = [
'' , 'bar=456' , 'bar=456' , 'abc=789&bar=456'
,'' , 'bar=456' , 'bar=456' , 'abc=789&bar=456'
,'' , 'bar=456' , 'bar=456' , 'abc=789&bar=456'
,'xfoo' , 'xfoo&bar=456' , 'bar=456&xfoo' , 'abc=789&xfoo&bar=456'
,'xfoo=' , 'xfoo=&bar=456' , 'bar=456&xfoo=' , 'abc=789&xfoo=&bar=456'
,'xfoo=123', 'xfoo=123&bar=456', 'bar=456&xfoo=123', 'abc=789&xfoo=123&bar=456'
,'foox' , 'foox&bar=456' , 'bar=456&foox' , 'abc=789&foox&bar=456'
,'foox=' , 'foox=&bar=456' , 'bar=456&foox=' , 'abc=789&foox=&bar=456'
,'foox=123', 'foox=123&bar=456', 'bar=456&foox=123', 'abc=789&foox=123&bar=456'
];
for(var i = 0; i < tests.length; i++) {
var output = tests[i].replace(regex, '');
var success = (output == expected[i]);
$('#output').append(
'<tr class="' + (success ? 'passed' : 'failed') + '">'
+ '<td>' + (success ? 'PASS' : 'FAIL') + '</td>'
+ '<td>' + escapeHtml(tests[i]) + '</td>'
+ '<td>' + escapeHtml(output) + '</td>'
+ '<td>' + escapeHtml(expected[i]) + '</td>'
+ '</tr>'
);
}
});
#output {
border-collapse: collapse;
}
#output tr.passed { background-color: #af8; }
#output tr.failed { background-color: #fc8; }
#output td, #output th {
border: 1px solid black;
padding: 2px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="output">
<tr>
<th>Succ?</th>
<th>Input</th>
<th>Output</th>
<th>Expected</th>
</tr>
</table>
推荐答案
如果你只想在一个正则表达式中做到这一点,你可以这样做:
If you want to do this in just one regular expression, you could do this:
/&foo(=[^&]*)?|^foo(=[^&]*)?&?/
这是因为您需要在 foo=... 之前匹配一个&符号,或者在之后匹配一个符号,或者两者都不匹配,但不能同时匹配两者.
This is because you need to match either an ampersand before the foo=..., or one after, or neither, but not both.
老实说,我认为您这样做的方式更好:在单独的步骤中删除尾随的&符号.
To be honest, I think it's better the way you did it: removing the trailing ampersand in a separate step.
这篇关于从查询字符串中删除一个参数的正则表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!