将匹配字符串中最后出现的点的正则表达式

Posted

技术标签:

【中文标题】将匹配字符串中最后出现的点的正则表达式【英文标题】:RegEx that will match the last occurrence of dot in a string 【发布时间】:2012-06-23 10:37:08 【问题描述】:

我有一个文件名,其中可以包含多个点,并且可以以任何扩展名结尾:

tro.lo.lo.lo.lo.lo.png

我需要使用正则表达式将最后出现的点替换为另一个字符串,例如@2x,然后再次替换点(非常像视网膜图像文件名),即:

tro.lo.png -> tro.lo@2x.png

这是我目前所拥有的,但它不会匹配任何东西......

str = "http://example.com/image.png";
str.replace(/.([^.]*)$/, " @2x.");

有什么建议吗?

【问题讨论】:

如果你想用正则表达式来做,你需要一个否定的前瞻,但你真的不应该 【参考方案1】:

您不需要正则表达式。 String.lastIndexOf 可以。

var str = 'tro.lo.lo.lo.lo.lo.zip';
var i = str.lastIndexOf('.');
if (i != -1) 
    str = str.substr(0, i) + "@2x" + str.substr(i);

See it in action.

更新:一个正则表达式解决方案,只是为了好玩:

str = str.replace(/\.(?=[^.]*$)/, "@2x.");

匹配文字点,然后断言((?=) 是 positive lookahead)直到字符串末尾没有其他字符是点。替换应包括匹配的一个点,除非您想删除它。

【讨论】:

返回那个字符所在位置的整数,对吧? 如何将整数与 .replace() 一起使用? @JacksonGariety:你不需要。 String.substr 会把事情总结一下。 很酷的答案!为什么这个代码比正则表达式更好/更高效/更少? @JacksonGariety。它的可读性更高,速度也更快。【参考方案2】:

只需在替换字符串中使用special replacement pattern$1

console.log("tro.lo.lo.lo.lo.lo.png".replace(/\.([^.]+)$/, "@2x.$1"));
// "tro.lo.lo.lo.lo.lo@2x.png"

【讨论】:

正确回答了 OP 的问题。 @Qtax:不完全是,因为如果最后一个点也是最后一个字符,它将不起作用。 @Jon,真的。那几乎是正确的。 ;) 但是/\.([^.]*)$/ 做到了,不需要环顾四周。 我不确定文件名是否可以将. 作为最后一个字符。【参考方案3】:

你可以使用表达式\.([^.]*?):

str.replace(/\.([^.]*?)$/, "@2x.$1");

您需要引用$1 子组以将该部分复制回结果字符串中。

【讨论】:

我认为这需要在 "$1@2x" 结束时再过一段时间才能工作,对吧? 这个答案有点草率 - 修复它以使其更有意义 w.r.t.你原来的正则表达式 我认为您在替换字符串中缺少.。我更喜欢转义.,但字符类可能更容易阅读。 .replace(/(.*)\./, "$1@2x.")。无论如何,对于使用 * 量词的贪婪属性的简单解决方案 +1。【参考方案4】:

工作演示 http://jsfiddle.net/AbDyh/1/

代码

var str = 'tro.lo.lo.lo.lo.lo.zip',
    replacement = '@2x.';
str = str.replace(/.([^.]*)$/, replacement + '$1');

$('.test').html(str);

alert(str);
​

【讨论】:

不完全。输出缺少一个点。 输出应该是 tro.lo.lo.lo.lo.lo@2x.zip 你输出 tro.lo.lo.lo.lo.lo@2xzip @gdoron lol 35 秒差 :) 干杯 更新版本在这里 jsfiddle.net/AbDyh/1 @gdoron you da man - 顺便说一句,我在想你什么时候会申请主持人角色!总之 SO 不是聊天小程序,只是推荐! 不会很快...我不想要这份工作,也没有时间。干杯。 :)【参考方案5】:

要匹配从字符串开头到(包括)最后一个字符出现的所有字符,请使用:

^.*\.(?=[^.]*$)  To match the last occurrence of the "." character

^.*_(?=[^.]*$)   To match the last occurrence of the "_" character

【讨论】:

【参考方案6】:

使用\. 匹配一个点。字符. 匹配任何字符。

因此str.replace(/\.([^\.]*)$/, ' @2x.')

【讨论】:

试试你的代码:"tro.lo.lo.lo.lo.lo.zip".replace(/\.([^\.]*)$/, ' @2x.') 它不起作用。对不起。 酷,对正则表达式一无所知【参考方案7】:

你可以这样做,

> "tro.lo.lo.lo.lo.lo.zip".replace(/^(.*)\./, "$1@2x");
'tro.lo.lo.lo.lo.lo@2xzip'

【讨论】:

【参考方案8】:

为什么不简单地拆分字符串并将所述后缀添加到倒数第二个条目:

var arr = 'tro.lo.lo.lo.lo.lo.zip'.split('.');
arr[arr.length-2] += '@2x';
var newString = arr.join('.');

【讨论】:

【参考方案9】:
'tro.lo.lo.lo.lo.lo.png'.replace(/([^\.]+).+(\.[^.]+)/, "$1.@x2$2")

【讨论】:

以上是关于将匹配字符串中最后出现的点的正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式入门边界

仅匹配指定字符的最后一次出现的正则表达式

正则表达式在匹配字符串之后查找最大数字的最后一次出现

js 正则获取匹配部分最后一个内容

正则表达式以啥结尾

正则表达式:匹配字符的第一次出现