Javascript 正则表达式替换部分子字符串未按预期工作?

Javascript regex to replace part of substring not working as expected?

提问人:Sampgun 提问时间:12/5/2022 最后编辑:Sampgun 更新时间:12/5/2022 访问量:60

问:

我正在研究时间和子午线。

我本来可以有或或或基本上我想做的是当它发生时将第一个转换为第二个'2:0 a. m.''2:0 am''3:0 p. m.''3:0 pm'

我的尝试:

console.info('2:0 a. m.'.replace(/(.*?\s)([ampAMP]*?)/, "$1")); // 2:0 a. m.

这个我真的不明白......

'2:0 a. m.'.replace(/(.*?\s)([ampAMP]).*?([ampAMP])/, "$1"); // 2:0 .

这个有效,但看起来很奇怪,不确定这是最好的方法

'2:0 a. m.'.replace(/(.*?\s)([ampAMP]).*?([ampAMP]).*?$/, "$1$2$3");

我几乎无法从时间中删除子午线,但是我怎样才能替换第一个空格之后所有不匹配的字符?[aAmMpP]

JavaScript 正则表达式 替换 子字符串 匹配

评论

1赞 The fourth bird 12/5/2022
也许您可以匹配多种可能的格式 regex101.com/r/gkjFjs/1\b(\d+)\s*:\s*(\d+)\s*([ap])\.\s*m\.

答:

1赞 Sampgun 12/5/2022 #1

目前,经过多次尝试,这确实有效,但不是很干净

let time = "02:00 p. m.";
time = time.replace(/(.*?\s)([ampAMP]).*?([ampAMP]).*?$/, "$1$2$3");
console.log(time);

与我选择的答案

let time = "02:00 a. m.";
time = time.replace(/\b(\d{1,2})\s*:\s*(\d{1,2})\s*([ap])\.\s*m\./i, "$1:$2 $3m");
console.log(time);

但顺便说一句,我最终这样做了:

let time = "02:00 a. m.";
time = time .replace(/\.\s*/g, "");
console.log(time);

因为虽然很好,但我有性能问题。

希望对您有所帮助

2赞 The fourth bird 12/5/2022 #2

如果要匹配 am 或 pm,则 using 仅匹配单个字符。如果您使用它两次,那么您将允许它不是有效的格式。[ampAMP]mm

您可以使模式匹配更多变化并捕获您想要保留的内容。然后在替换中,使用捕获组创建所需的格式。

如果点是必填项:

\b(\d{1,2})\s*:\s*(\d{1,2})\s*([ap])\.\s*m\.
  • \b词边界
  • (\d{1,2})捕获组 1,匹配 1-2 位数字
  • \s*:\s*可选空格字符之间的数学运算:
  • (\d{1,2})捕获组 2,匹配 1-2 位数字
  • \s*匹配可选的空格字符
  • ([ap])捕获组 3,匹配或ab
  • \.\s*m\.匹配可选的空格字符和.m.

观看正则表达式演示

在替换使用中(正如您已经知道的那样,您已经匹配了字符)m

$1:$2 $3m

const regex = /\b(\d{1,2})\s*:\s*(\d{1,2})\s*([ap])\.\s*m\./;
[
  "2:0 a. m.",
  "2:0 p. m.",
  "3:0 p. m.",
  "3:0p.m.",
  "2:0 am"
].forEach(s => console.log(s.replace(regex, "$1:$2 $3m")));

像特定模式一样多一点时间,允许秒部分使用可选的数字 0-5:

\b([0-1]?[0-9]|2[0-3])\s*:\s*([0-5]?[0-9])\s*([ap])\.\s*m\.

正则表达式演示

评论

1赞 Sampgun 12/5/2022
我用你的来改进我的,但你的它更快。感谢您的解决方案和详细说明。我只是添加了标志来处理可能的奇怪格式,例如iA.m.
0赞 Sampgun 12/5/2022
啊,很高兴你注意到你错过了替换!啊哈,我得先试试!: