Javascript RegExp 替换为负前瞻

发布于 2024-09-24 11:46:41 字数 471 浏览 0 评论 0原文

我正在尝试使用 JS 替换当前页面的查询字符串中的某些值。例如:从 category=Old Valuecategory=New Value。 代码看起来像这样:

var sNewValue = 'New Value';
sQueryString = sQueryString.replace(/category=[^&]+&?/, 'category=' + sNewValue);

除了带有&符号的值之外,它工作正常。幸运的是,所有 & 符号都是 URL 编码的,所以我知道我应该丢弃 & 之前的 amp;。我想我应该使用前瞻,但我不知道如何。我尝试了这个正则表达式,但没有成功: /category=[^&(?!amp;)]+&?/

谢谢

I am trying to replace some value in the query string of the current page using JS. Eg: from category=Old Value to category=New Value.
To code looks like this:

var sNewValue = 'New Value';
sQueryString = sQueryString.replace(/category=[^&]+&?/, 'category=' + sNewValue);

It works fine except for values that have ampersands. Luckily all the ampersands are URL encoded, so I know I should discard the amp; before the &. I think I should use lookaheads, but I don't know how. I tried this regular expression, but with no luck: /category=[^&(?!amp;)]+&?/

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

辞慾 2024-10-01 11:46:41

为什么 & 符号被编码为 &而不是 %26?或者我读错了你的问题?

如果需要这样,那么如果您首先将其分解为名称/值对,则处理此查询字符串可能会更容易。

var pairStrings = sQueryString.split(/&(?!amp;)/gi);

然后您可以使用每个值,而不必担心它是否包含编码的 &或不。

Why are ampersands being encoded as & instead of %26? Or am I reading your question wrong?

If that's the way it needs to be, it might be easier for you to deal with this query string if you break it into name/value pairs first.

var pairStrings = sQueryString.split(/&(?!amp;)/gi);

Then you can work with each value without worrying if it contains an encoded & or not.

§普罗旺斯的薰衣草 2024-10-01 11:46:41

您根本不需要指定以下 &

var sNewValue = 'New Value';
sQueryString = sQueryString.replace(/(^|&)category=[^&]*/, '$1category=' + encodeURIComponent(sNewValue));

因为 [^&] 已经匹配除 & 之外的任何字符。此外,如果category是最后一个参数,则后面甚至没有&

You don’t need to specify a following & at all:

var sNewValue = 'New Value';
sQueryString = sQueryString.replace(/(^|&)category=[^&]*/, '$1category=' + encodeURIComponent(sNewValue));

Because [^&] does already match any character except &. Furthermore, if category is the last parameter, there even is no following &.

香草可樂 2024-10-01 11:46:41

好吧,我想我确实找到了你需要的东西。

var sNewValue = 'category=New Value&';
sQueryString = sQueryString.replace(/category=([^&]|&)*&/, sNewValue)

OK, I think I actually found what you need.

var sNewValue = 'category=New Value&';
sQueryString = sQueryString.replace(/category=([^&]|&)*&/, sNewValue)
無處可尋 2024-10-01 11:46:41

您可以尝试:

var sNewValue = 'New Value';
sQueryString = sQueryString.replace(/\bcategory=[^&]*/, 'category=' + sNewValue);

即使类别前面有 ?,如 /foo.php?category=bar 中,这也会替换

You can try:

var sNewValue = 'New Value';
sQueryString = sQueryString.replace(/\bcategory=[^&]*/, 'category=' + sNewValue);

This will replace even if category is preceded by ? as in /foo.php?category=bar

走野 2024-10-01 11:46:41

/(\bcategory=)(([^&]|&\;)*)/

这包括许多不同的场景:

   var s1 = 'http://www.foobar.com/?category=old&foo=bar';
   var s2 = 'http://www.foobar.com/?category=old';
   var s3 = 'http://www.foobar.com/?foo=bar&category=old';
   var s4 = 'http://www.foobar.com/?foo=bar&category=old&value';
   var s5 = 'http://www.foobar.com/?foo=bar&category=old&value&bar=foo';

   var n  = 'NewVal';

   console.log( s1.replace(/(\bcategory=)(([^&]|&\;)*)/, "$1" + n) );
   console.log( s2.replace(/(\bcategory=)(([^&]|&\;)*)/, "$1" + n) );
   console.log( s3.replace(/(\bcategory=)(([^&]|&\;)*)/, "$1" + n) );
   console.log( s4.replace(/(\bcategory=)(([^&]|&\;)*)/, "$1" + n) );
   console.log( s5.replace(/(\bcategory=)(([^&]|&\;)*)/, "$1" + n) );

   // s1 output: http://www.foobar.com/?category=NewVal&foo=bar
   // s2 output: http://www.foobar.com/?category=NewVal
   // s3 output: http://www.foobar.com/?foo=bar&category=NewVal
   // s4 output: http://www.foobar.com/?foo=bar&category=NewVal
   // s5 output: http://www.foobar.com/?foo=bar&category=NewVal&bar=foo

您可能想要添加全局开关。

/(\bcategory=)(([^&]|&\;)*)/

This includes the many different scenarios:

   var s1 = 'http://www.foobar.com/?category=old&foo=bar';
   var s2 = 'http://www.foobar.com/?category=old';
   var s3 = 'http://www.foobar.com/?foo=bar&category=old';
   var s4 = 'http://www.foobar.com/?foo=bar&category=old&value';
   var s5 = 'http://www.foobar.com/?foo=bar&category=old&value&bar=foo';

   var n  = 'NewVal';

   console.log( s1.replace(/(\bcategory=)(([^&]|&\;)*)/, "$1" + n) );
   console.log( s2.replace(/(\bcategory=)(([^&]|&\;)*)/, "$1" + n) );
   console.log( s3.replace(/(\bcategory=)(([^&]|&\;)*)/, "$1" + n) );
   console.log( s4.replace(/(\bcategory=)(([^&]|&\;)*)/, "$1" + n) );
   console.log( s5.replace(/(\bcategory=)(([^&]|&\;)*)/, "$1" + n) );

   // s1 output: http://www.foobar.com/?category=NewVal&foo=bar
   // s2 output: http://www.foobar.com/?category=NewVal
   // s3 output: http://www.foobar.com/?foo=bar&category=NewVal
   // s4 output: http://www.foobar.com/?foo=bar&category=NewVal
   // s5 output: http://www.foobar.com/?foo=bar&category=NewVal&bar=foo

You may want to add a global switch.

‘画卷フ 2024-10-01 11:46:41

JavaScript 正则表达式中不会出现向后查找。您确实会先行查看,但它在 IE 中并不可靠,因此最好避免,除非您真的知道自己在做什么。

[^&(?!amp;)]+&

是的,这确实没有任何意义。您不能在 [] 字符组中使用前瞻:您在这里所说的是匹配不是 &(?!amp;)

然而,无论如何你都不应该看到 & :你应该处理一个简单的、未编码的查询字符串,例如。从 location.search 获取。 (如果您使用正则表达式修改字符串中的 HTML 标记,则会遇到非常非常大的问题。)

如果您从 location.search 获取查询字符串,如果有任何查询,前面会有一个?。因此,您可以将开头与 &? 匹配,并执行正则表达式匹配:

location.search.replace(
    /([?&;]category=)[^&;]+/,
    '$1'+encodeURIComponent(sNewValue)
);

注意我还包括 ; 作为可能的内容分隔符按照 HTML4 第 B.2.2 节,并使用 encodeURIComponent 以便无效字符(如空格)和特殊字符(如 &)本身得到正确的 URL 编码。还有字符 $,它在正则表达式替换字符串中具有特殊含义。

这仍然很混乱,并且不能处理 URL 编码的参数名称(即 c%61tegory 是表示 category 的有效替代方式)或带有同名。如果您想更加健壮,您可以转储正则表达式并执行完整的查询字符串解析/重建。请参阅此答案中的函数并执行:

var lookup= queryToLookup(location.search);
lookup['category']= ['New value'];
var query= lookupToQuery(lookup);

You don't get lookbehind in JavaScript regular expressions. You do get lookahead, but it is unreliable in IE, so best avoided unless you really know what you're doing.

[^&(?!amp;)]+&

yeah, this doesn't really make any sense. You can't use lookahead in a [] character group: what you're saying here is match characters that aren't &, (, ?, ! , a, m, p, ;, or ).

However you should not see & anyway: you should be working on a plain, unencoded query string, eg. as fetched from location.search. (If you are hacking at HTML markup in a string with regex you've got much, much bigger problems.)

If you are getting the query string from location.search, you'll have a ? on the front if there's any query. So you can match the beginning with either & or ?, and do your regex match on:

location.search.replace(
    /([?&;]category=)[^&;]+/,
    '$1'+encodeURIComponent(sNewValue)
);

note I have also included ; as a possible separator as per HTML4 section B.2.2, and used encodeURIComponent so that invalid characters like spaces and special characters like & itself get properly URL-encoded. Also the character $, which otherwise has special meaning in a regexp replacement string.

This is still quite messy, and doesn't cope with URL-encoded parameter names (ie c%61tegory is a valid alternative way of saying category) or multiple parameters with the same name. If you want to be more robust about it you could dump the regexps and do full query string parsing/reconstruction. See the functions from this answer and do:

var lookup= queryToLookup(location.search);
lookup['category']= ['New value'];
var query= lookupToQuery(lookup);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文