Javascript使用正则表达式替换非捕获组

时间:2022-12-06 17:15:30

I'm trying to remove the ordinals in a date string.

我正在尝试删除日期字符串中的序数。

I need to verify that there is at least one digit before the ordinal, that way we know it is an ordinal and not part of a word. Here is the proper regex:

我需要验证序数之前至少有一个数字,这样我们就知道它是一个序数而不是一个单词的一部分。这是正确的正则表达式:

/(?:\d)(st|nd|rd|th)/g

Now, when I do a regex replace on a string in Javascript, I end up replacing the leading digit before the ordinal that was "captured" by my non-capturing group as well, which you can see here:

现在,当我在Javascript中对字符串进行正则表达式替换时,我最终替换了非捕获组“捕获”序数之前的前导数字,您可以在此处看到:

var inpt;

function swapText()
{
  var str = inpt.value;
  var reg = /(?:\d)(st|nd|rd|th)/g;

  str = str.replace(reg, "");
  
  inpt.value = str;
}

function init()
{
  inpt = document.getElementById('str_data');
  var btn = document.getElementById('swap_btn');
  btn.addEventListener('click', swapText, false);
}

setTimeout(init, 0);
body {
  font:13.23px "Open Sans", Verdana, sans-serif;
}

input {
  min-height:30px;
  height:auto;
  width:auto;
  padding: 6px 8px;
  color: #424242;
}

.btn {
	display: inline-block;
	padding: 8px 12px;
	margin-bottom: 0;
	font-size: 14px;
	font-weight: 500;
	line-height: 1.428571429;
	text-align: center;
	white-space: nowrap;
	vertical-align: middle;
	cursor: pointer;
	border: 1px solid transparent;
	border-radius: 4px;
	-webkit-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	-o-user-select: none;
	user-select: none;
}

.btn-success {
	color: #fff;
	background-color: #5cb85c;
	border-color: #4cae4c;
}

.btn-primary {
    color: #fff;
    background-color: #337ab7;
    border-color: #2e6da4;
}

input, button, select, textarea {
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
}

button, html input[type="button"], input[type="reset"], input[type="submit"] {
  cursor: pointer;
  -webkit-appearance: button;
}

button, select {
  text-transform: none;
}
<input id="str_data" value="The 1st, 2nd, 3rd, and 4th" />
<button id="swap_btn" class="btn btn-primary" >
  Swap Text
</button>

Code snippet not working? Check this JSFiddle.

代码段不起作用?检查这个JSFiddle。

Now, after poking around the suggested matching questions, I found that in some languages, non-capturing groups are ignored in regex matches. Is this the case for Javascript?

现在,在探讨了建议的匹配问题之后,我发现在某些语言中,在正则表达式匹配中会忽略非捕获组。这是Javascript的情况吗?

For example, if I have the string The 1st, 2nd, 3rd, and 4th and I were to run a string.match with the regex I provided above, this would be my output:

例如,如果我有字符串第1,第2,第3和第4,我将使用上面提供的正则表达式运行string.match,这将是我的输出:

var str = "The 1st, 2nd, 3rd, and 4th";
var opt = JSON.stringify(str.match(/(?:\d)(st|nd|rd|th)/g));
document.body.innerHTML = opt;

As you can see, my non-capturing group was ignored. Is this why my string.replace ignores my capturing group as well? If so, then how should I replace the "ordinal" in a date string and verify that there is a leading digit (and leave the leading digit of course) in Javascript? Thanks!

如您所见,我的非捕获组被忽略了。这就是为什么我的string.replace也忽略了我的捕获组?如果是这样,那么我应该如何替换日期字符串中的“序数”并验证在Javascript中是否存在前导数字(当然还有前导数字)?谢谢!

UPDATE: Here is a snippet with the accepted Regex

更新:这是一个与接受的正则表达式的片段

var inpt;

function swapText()
{
  var str = inpt.value;
  var reg = /(\d)(?:st|nd|rd|th)/g;

  str = str.replace(reg, "$1");
  
  inpt.value = str;
}

function init()
{
  inpt = document.getElementById('str_data');
  var btn = document.getElementById('swap_btn');
  btn.addEventListener('click', swapText, false);
}

setTimeout(init, 0);
body {
  font:13.23px "Open Sans", Verdana, sans-serif;
}

input {
  min-height:30px;
  height:auto;
  width:auto;
  padding: 6px 8px;
  color: #424242;
}

.btn {
	display: inline-block;
	padding: 8px 12px;
	margin-bottom: 0;
	font-size: 14px;
	font-weight: 500;
	line-height: 1.428571429;
	text-align: center;
	white-space: nowrap;
	vertical-align: middle;
	cursor: pointer;
	border: 1px solid transparent;
	border-radius: 4px;
	-webkit-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	-o-user-select: none;
	user-select: none;
}

.btn-success {
	color: #fff;
	background-color: #5cb85c;
	border-color: #4cae4c;
}

.btn-primary {
    color: #fff;
    background-color: #337ab7;
    border-color: #2e6da4;
}

input, button, select, textarea {
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
}

button, html input[type="button"], input[type="reset"], input[type="submit"] {
  cursor: pointer;
  -webkit-appearance: button;
}

button, select {
  text-transform: none;
}
<input id="str_data" value="The 1st, 2nd, 3rd, and 4th" />
<button id="swap_btn" class="btn btn-primary" >
  Swap Text
</button>

2 个解决方案

#1


6  

Use a capturing group and replace by $1.use replace instead of match.

使用捕获组并替换$ 1.use替换而不是匹配。

(\d)(?:st|nd|rd|th)

See demo.

见演示。

https://regex101.com/r/iJ7bT6/6

https://regex101.com/r/iJ7bT6/6

var re = /(\d)(?:st|nd|rd|th)/g; 
var str = 'The 1st, 2nd, 3rd, and 4th';
var subst = '$1'; 

var result = str.replace(re, subst);

#2


1  

When you pass a regext to .match() and the regex has the g option (global), the return value from match is an array of all the complete matches; the groups are not returned, just the complete matches. JavaScript isn't ignoring your non-capturing group (nor your capturing group), but because of the g flag you just don't get any information back about them.

将regext传递给.match()并且regex具有g选项(全局)时,match的返回值是所有完整匹配的数组;这些组不会被退回,只有完整的比赛。 JavaScript不会忽略你的非捕获组(也不是你的捕获组),但由于g标志,你只是没有得到任何关于它们的信息。

#1


6  

Use a capturing group and replace by $1.use replace instead of match.

使用捕获组并替换$ 1.use替换而不是匹配。

(\d)(?:st|nd|rd|th)

See demo.

见演示。

https://regex101.com/r/iJ7bT6/6

https://regex101.com/r/iJ7bT6/6

var re = /(\d)(?:st|nd|rd|th)/g; 
var str = 'The 1st, 2nd, 3rd, and 4th';
var subst = '$1'; 

var result = str.replace(re, subst);

#2


1  

When you pass a regext to .match() and the regex has the g option (global), the return value from match is an array of all the complete matches; the groups are not returned, just the complete matches. JavaScript isn't ignoring your non-capturing group (nor your capturing group), but because of the g flag you just don't get any information back about them.

将regext传递给.match()并且regex具有g选项(全局)时,match的返回值是所有完整匹配的数组;这些组不会被退回,只有完整的比赛。 JavaScript不会忽略你的非捕获组(也不是你的捕获组),但由于g标志,你只是没有得到任何关于它们的信息。