我试图找到一个与基本字符串匹配的正则表达式,而没有可选的尾随数字(_123
)。 例如:
lorem_ipsum_test1_123
->捕获 lorem_ipsum_test1
lorem_ipsum_test2
->捕获 lorem_ipsum_test2
我尝试使用以下表达式,但仅在尾随_number时才有效。
/(.+)(?>_[0-9]+)/
/(.+)(?>_[0-9]+)?/
同样,仅在没有尾随_number的情况下添加?
(零个或多个)量词才有效,否则,尾随_number只是第一次捕获的一部分。
有什么建议吗?
答案 0 :(得分:2)
您可以使用以下表达式:
^(?:[^_]+_)+(?!\d+$)[^_]+
^
锚定字符串的开头。(?:[^_]+_)+
重复的非捕获组。除_
以外的其他任何字符之后均取反的字符集。{li}
_
在字符串末尾的数字负向查找。(?!\d+$)
除[^_]+
以外的任何其他字符集。正则表达式演示here。
请注意,Regex演示中字符集中的_
仅用于演示目的,在用作Javascript模式时,应将其删除。
JavaScript演示
\n
答案 1 :(得分:1)
您可以匹配任何字符,并使用否定的前瞻来断言其后不是下划线,一个或多个数字以及字符串的结尾:
^(?:(?!_\d+$).)*
说明
^
声明字符串的开头(?:
非捕获组
(?!
否定断言来断言右边的内容不是
_\d+$
匹配下划线,一个或多个数字并声明字符串的结尾.)
匹配任意字符并提前否定否定)*
关闭非捕获组并重复零次或多次
const strings = [
"lorem_ipsum_test1_123",
"lorem_ipsum_test2"
];
let pattern = /^(?:(?!_\d+$).)*/;
strings.forEach((s) => {
console.log(s + " ==> " + s.match(pattern)[0]);
});
答案 2 :(得分:1)
您要的
/^(.*?)(?:_\d+)?$/
请参见regex demo。这里的要点是,第一个点图案必须是非贪婪的,_\d+
应该用一个可选的非捕获组包裹,并且整个图案(尤其是结尾)必须用锚点包围。
详细信息
^
-字符串的开头(.*?)
-捕获组1:除换行符以外的任何零个或多个字符,由于非贪婪(“ lazy” )量词{{1 }} *?
-一个可选的非捕获组,匹配(?:_\d+)?
的1或0次出现,然后匹配1+个数字_
-字符串的结尾。但是,使用简单的替换方法似乎更容易
$
如果字符串以s = s.replace(/_\d+$/, '')
和1+数字结尾,则将删除子字符串,否则,字符串将保持不变。
请参见this regex demo。
答案 3 :(得分:0)
尝试检查字符串是否包含结尾数字。如果是这样,您只能得到另一部分。否则,您将得到整个字符串。
var str = "lorem_ipsum_test1_123"
if(/_[0-9]+$/.test(str)) {
console.log(str.match(/(.+)(?=_[0-9]+)/g))
} else {
console.log(str)
}
或者更简洁:
str = str.replace(/_[0-9]+$/g, "")