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:
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>
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:
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.
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?
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:
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!
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>
Share
Improve this question
edited Jan 13, 2016 at 22:13
WebWanderer
asked Jan 13, 2016 at 18:11
WebWandererWebWanderer
10.9k5 gold badges34 silver badges53 bronze badges
8
- 1 Do you mean to obtain this? – Wiktor Stribiżew Commented Jan 13, 2016 at 18:16
- JavaScript does not ignore non-capturing groups. – Pointy Commented Jan 13, 2016 at 18:20
- YES @stribizhev I did! Thats fantastic! Thank you! – WebWanderer Commented Jan 13, 2016 at 18:21
- vks posted the same answer. – Wiktor Stribiżew Commented Jan 13, 2016 at 18:22
-
1
Ok, here it is: there is matching with and without capturing in regex. When you capture a part of a pattern (with
()
) this value is saved in a memory buffer. So, capture groups also serve as grouping and subvalue saving constructs. Non-capturing groups ((?:...)
) only group (good for alternatives or optional sequence definition), do not save any subvalues. The rule of thumb for replacing is match and capture what you need to get and only match what you do not need. – Wiktor Stribiżew Commented Jan 13, 2016 at 21:01
3 Answers
Reset to default 11Use a capturing group and replace by $1
. Use replace instead of match.
(\d)(?:st|nd|rd|th)
See demo.
https://regex101./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);
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 plete matches; the groups are not returned, just the plete 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.
Variable date replace in url
posutochnaja-arenda-nedvizhimost-v-yalte/zhk-morskoy-spusk-v-yalte-id20879?date_from_to=01.12.2021-03.12.2021&clear_cache=Y&_r=3298#rooms-header-block
https://regex101./r/fgjGuo/1