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>
Use a capturing group and replace by $1
. Use replace instead of match.
(\d)(?:st|nd|rd|th)
See demo.
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);
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With