【发布时间】:2010-12-22 23:54:41
【问题描述】:
我正在寻找一个正则表达式来从查询字符串中删除单个参数,如果可能的话,我想在单个正则表达式中执行此操作。
假设我想删除foo 参数。现在我用这个:
/&?foo\=[^&]+/
只要foo 不是查询字符串中的第一个参数,它就可以工作。如果是,那么我的新查询字符串以 & 符号开头。 (例如,“foo=123&bar=456”给出的结果是“&bar=456”。)现在,我只是在正则表达式之后检查查询字符串是否以 & 符号开头,如果是则将其截断。
示例边缘情况:
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
编辑
好的,正如 cmets 中指出的那样,边缘情况比我最初考虑的要多得多。我得到了以下正则表达式来处理所有这些:
/&foo(\=[^&]*)?(?=&|$)|^foo(\=[^&]*)?(&|$)/
这是从 Mark Byers's answer 修改的,这就是我接受它的原因,但 Roger Pate 的意见也有很大帮助。
这是我正在使用的全套测试用例,以及用于测试它们的 Javascript sn-p:
$(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>
【问题讨论】:
-
其他边缘情况:
oopsfoo=123、foo、foo=---都是唯一、第一个、最后一个和中间参数。 (所以这里总共 12 个) -
@Roger Pate:谢谢,没想到。还有
foobar=123、foobar和foobar=,以确保foo的检查不会命中他们 -
如果输入是
foo=,预期的输出是什么? -
@Mark Byers:空字符串。几分钟后,我将提供一个更完整的示例输出,当我得到我的测试脚本时...
-
谢谢,java版本好像是:String regex = "&"+paramToRemove+"(\\=[^&]*)?(?=&|$)|^"+paramToRemove+" (\\=[^&]*)?(&|$)";
标签: regex query-string