正则表达式捕获,带有可选的下划线和数字

时间:2018-09-10 19:56:24

标签: javascript regex

我试图找到一个与基本字符串匹配的正则表达式,而没有可选的尾随数字(_123)。 例如:

lorem_ipsum_test1_123->捕获 lorem_ipsum_test1

lorem_ipsum_test2->捕获 lorem_ipsum_test2

我尝试使用以下表达式,但仅在尾随_number时才有效。 /(.+)(?>_[0-9]+)/ /(.+)(?>_[0-9]+)?/ 同样,仅在没有尾随_number的情况下添加?(零个或多个)量词才有效,否则,尾随_number只是第一次捕获的一部分。

有什么建议吗?

4 个答案:

答案 0 :(得分:2)

您可以使用以下表达式:

^(?:[^_]+_)+(?!\d+$)[^_]+
  • ^锚定字符串的开头。
  • (?:[^_]+_)+重复的非捕获组。除_以外的其他任何字符之后均取反的字符集。{li}
  • _在字符串末尾的数字负向查找。
  • (?!\d+$)[^_]+以外的任何其他字符集。

正则表达式演示here

请注意,Regex演示中字符集中的_仅用于演示目的,在用作Javascript模式时,应将其删除。


JavaScript演示

\n

答案 1 :(得分:1)

您可以匹配任何字符,并使用否定的前瞻来断言其后不是下划线,一个或多个数字以及字符串的结尾:

^(?:(?!_\d+$).)*

说明

  • ^声明字符串的开头
  • (?:非捕获组
    • (?!否定断言来断言右边的内容不是
      • _\d+$匹配下划线,一个或多个数字并声明字符串的结尾
    • .)匹配任意字符并提前否定否定
  • )*关闭非捕获组并重复零次或多次

Regex demo

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, "")