Reputation: 441
New to regex and I need to pattern match on some dates to change the format.
I'm going from mm/dd/yy
to yyyy-mm-dd
where there are no entries prior to 2000.
What I'm unfamiliar with is how to group things to use their respective references of \1
, \2
, etc.
Would I first want to match on mm/dd/yy
with something like ( \d{2} ) ( \/\d{2} ) ( \/\d{2} )
or is it as easy as \d\d/\d\d/\d\d
?
Assuming my first grouping is partially the right idea, I'm looking to do something like:
:%s/old/new/g
:%s/ ( \d{2} ) ( \/\d{2} ) ( \/\d{2} ) / ( 20+\3) - (\3) - (\1) /g
EDIT: Sorry, the replace is going to a yyyy-mm-dd format
with hyphens, not the slash.
Upvotes: 7
Views: 2731
Reputation: 17853
I was going to comment on another answer but it got complicated.
Mind the magic
setting. If you want unescaped parens to do grouping, you need to include \v
somewhere in your pattern. (See :help magic
).
You can avoid escaping the slashes if you use something other than slashes in the :s
command.
You are close. :) You don't want all of those spaces though as they'll require spaces in the same places to match.
My solution, where I use \v
so I don't need to escape the parens and exclamation points so I can use slashes in my pattern without escaping them:
:%s!\v(\d{2})/(\d{2})/(\d{2})!20\3-\2-\1!g
This will match "inside" items that start or end with three or more digits though, too. If you can give begin/end criteria then that'd possibly be helpful. Assuming that simple "word boundary" conditions work, you can use <>
:
:%s!\v<(\d{2})/(\d{2})/(\d{2})>!20\3-\2-\1!g
To critique yours specifically (for learning!):
:%s/ ( \d{2} ) ( \/\d{2} ) ( \/\d{2} ) / ( 20+\3) - (\3) - (\1) /g
\( \)
or \v
to work\{2}
unless you use \v
+
after the 20 in the outputUpvotes: 11
Reputation: 3554
ok, try this one:
:0,$s#\(\d\{1,2\}\)/\(\d\{1,2\}\)/\(\d\{1,2\}\)#20\3-\2-\1#g
I've removed a lot of the spaces, both in the matching section and the replacement section, and most of parens, because the format you were asking for didn't have it.
Some things of note:
Upvotes: 1
Reputation: 885
Try this:
:%s/\(\d\{2}\)\/\(\d\{2}\)\/\(\d\{2}\)/20\3-\2-\1/g
The bits you're interested in are: \(...\)
- capture; \d
- a digit; \{N}
- N occurrences; and \/
- a literal forward slash.
So that's capturing two digits, skipping a slash, capturing two more, skipping another slash, and capturing two more, then replacing it with "20" + the third couplet + "-" + the second couplet + "-" + the first couplet. That should turn "dd/mm/yy" into "20yy-mm-dd".
Upvotes: 1
Reputation: 2887
For the match: (\d{2})\/(\d{2})\/(\d{2})
For the replace: 20\3\/\1\/\2
Upvotes: -1