如何使用 javascript regexp 替换字符串的一部分
Posted
技术标签:
【中文标题】如何使用 javascript regexp 替换字符串的一部分【英文标题】:How to replace part of a string using javascript regexp 【发布时间】:2020-04-20 13:29:45 【问题描述】:我有这段文字需要替换css的宽度部分:
oldStyle = "width:90%;height:inherit;padding-right: 15px;padding-left: 15px;margin-right: auto;margin-left: auto;"
我有这个代码表达式或模式:
oldStyle.replace(new RegExp("width:[0-9]+%;.*$", "g"), "width:25%;")
但结果是:
"width:25%;"
它缺少 css 的其余部分:
"height:inherit;padding-right: 15px;padding-left: 15px;margin-right: auto;margin-left: auto;"
结果应该是:
"width:25%;height:inherit;padding-right: 15px;padding-left: 15px;margin-right: auto;margin-left: auto;"
如何只更改 CSS 的宽度部分并保持其他 CSS 的其余部分不变?
【问题讨论】:
为什么不使用简单的字符串操作而不是正则表达式? 试试new RegExp("width:[0-9]+%;", "g")
我还有其他依赖此方法的代码
JB31 没问题,但如果 oldStyle 有 max-width:40%;这也会改变最大宽度
(?:^|;|\s)width:[0-9]+(?:px|%)
是否用作正则表达式?
【参考方案1】:
您不需要为此任务使用正则表达式。还有更简单的选择。
基本的字符串操作
function changeWidth(style, newValue)
const segments = style
.slice(0, -1) //remove last `;`
.split(';');
const nonWidthSegments = segments.filter(segment => !segment.startsWith("width"));
return nonWidthSegments
.concat(`width: $newValue`)
.join(';')
.concat(';'); //add the last `;`
console.log(changeWidth(
"width:90%;height:inherit;padding-right: 15px;padding-left: 15px;margin-right: auto;margin-left: auto;",
"45px"
));
console.log(changeWidth(
"margin: auto;",
"45px"
));
console.log(changeWidth(
"",
"45px"
));
DOM 操作
function changeWidth(style, newValue)
const el = document.createElement("div");
el.setAttribute("style", style);
el.style.width = newValue;
return el.getAttribute("style");
console.log(changeWidth(
"width:90%;height:inherit;padding-right: 15px;padding-left: 15px;margin-right: auto;margin-left: auto;",
"45px"
));
console.log(changeWidth(
"margin: auto;",
"45px"
));
console.log(changeWidth(
"",
"45px"
));
只是想更新 VLAZ 建议的答案,经过更多测试后,此代码实际上因 .startsWith
函数而失败,因为假设您想更改 border-bottom-left-radius
并且通过的旧样式具有旧样式border-bottom
,那么这将过滤掉旧样式变量中的border-bottom
,而不是添加或更新border-bottom-left-radius
。
所以我稍微修改了函数,仍然采用 VLAZ 的建议:
传递的键是样式属性,例如 border
或 border-top
或 width
或任何其他样式属性。
刚刚进一步编辑,因为newStyle
部分没有通过newValue
。
function changeWidth(oldStyle, newValue, key)
const segments = oldStyle
.slice(0, -1) //remove last `;`
.split(';');
var matchSegement = "";
for (var t = 0; t < segments.length; t++)
if (segments[t].split(":")[0] == key)
matchSegement = segments[t];
var nonWidthSegments = segments.filter(function (segment)
return segment != matchSegement;
);
var newStyle = nonWidthSegments
.concat(key + `:$newValue`)
.join(';')
.concat(';');
【讨论】:
他想使用regexp
,而不是其他方法
@AhmetZeybek 我发现很多人想使用正则表达式,因为他们不知道任何其他方式。许多未来的访问者也可能会从了解 regex 不是金锤中受益。
@AhmetZeybek 如果你想知道我为什么喜欢给出替代方案的原因,那么你会注意到这里的每一个正则表达式答案都是错误的。不是正则表达式无法正确编写,而是很容易错误地编写它。
最后我使用了 VLAZ 方法,我使用 regexp 尝试了其他建议,但是当我添加 VLAZ 已回答的代码时,它很容易设置并集成到我的代码中,我让它完全正常工作现在。感谢大家的建议,但感谢 VLAZ 对其进行了排序!我会赞成其他建议和答案,因为它帮助我更多地理解正则表达式,但这是我一直在寻找的答案。【参考方案2】:
您可以使用下面的正则表达式来实现您想要的。正则表达式将用%
或px
或rem
和许多其他单位替换任何宽度;
string = "width:90%;height:inherit;padding-right: 15px;padding-left: 15px;margin-right: auto;margin-left: auto;"
console.log(string.replace(/width ?: ?[0-9]+(%|[a-z]+|);/ig,"width:25%;"))
【讨论】:
如果单位不是%
或px
或rem
怎么办?有many other units,也有可能没有单位。或者你甚至可能有width: auto
。这将在更多成功的情况下失败。
我已经更新了代码,在这种情况下它仍然可以工作。【参考方案3】:
这将更改字符串中以width
开头并以%;
结尾的任何值,您可以根据需要修改正则表达式
first = "width:90%;height:100%;padding-right: 15px;padding-left: 15px;margin-right: auto;margin-left: auto;"
second = "width:90%;height:inherit;padding-right: 15px;padding-left: 15px;margin-right: auto;margin-left: auto;"
third = "height:inherit;padding-right: 15px;padding-left: 15px;width:90%;margin-right: auto;margin-left: auto;"
console.log(first.replace(/width(.*?);/g,"width:25%;"))
console.log(second.replace(/width(.*?);/g,"width:25%;"))
console.log(third.replace(/width(.*?);/g,"width:25%;"))
【讨论】:
有many units,而不仅仅是%
。如果值是90px
,那么这很有可能会失败。在width: 90px; height: 100%;
的情况下,这可能是灾难性的胜利——height
属性将使用这个正则表达式被清除。
@VLAZ 是的,我忘了输入?
字符,现在它可以正常工作了。【参考方案4】:
仅将数值 width:90px;
替换为 width:40px;
或 width:90%;
到 width:40%;
str = "max-width:40px;width:90px;height:inherit;padding-right: 15px;padding-left: 15px;margin-right: auto;margin-left: auto;"
console.log(str.replace(/([^-]width)(:[0-9]\d+)(.*)/g,"$1:25$3"))
str = "max-width:40px;width:90%;height:inherit;padding-right: 15px;padding-left: 15px;margin-right: auto;margin-left: auto;"
console.log(str.replace(/([^-]width)(:[0-9]\d+)(.*)/g,"$1:25$3"))
【讨论】:
【参考方案5】:这部分width:[0-9]+%;
会找到一些百分比的宽度值,但是这部分.*$
匹配“直到字符串末尾的任何内容”。
但你不希望第二部分被width:25%;
替换,所以,直接放弃吧:
oldStyle.replace(new RegExp("width:[0-9]+%;", "g"), "width:25%;")
这个 RegExp 肯定会得到改进。正如人们在 cmets 中正确指出的那样,例如,它也将匹配 max-width:75%
并随后将其更改为 max-width:25%
。
但是,根据您的用例,它可能就足够了。
一般来说,考虑到可能出错的事情的数量,您希望在这种情况下避免使用 RegExp,直到您有其他选择。
【讨论】:
有many units,而不仅仅是%
。这完全有可能失败,特别是如果您使用 width: 90%
之类的东西 - 带有空格。
@VLAZ 我们不知道实际用例是什么,只有作者知道。 he 为什么在他的 RegExp 中使用了 %。可能,他只想替换带有百分比的值。以上是关于如何使用 javascript regexp 替换字符串的一部分的主要内容,如果未能解决你的问题,请参考以下文章