Package: datetime-matcher
datetime-matcher 📆←💬datetime-matcher is python module that enables an extension of regex which allows
matching, extracting, and reformatting stringified datetimes.It does so by providing an interface eerily similar to python's nativeremodule.It's mighty useful for doing things like bulk-renaming files with datetimes in their
filenames. But don't let us tell you what it's good for—give it a try yourself!Quick LinksGetting Started— Quick introduction in the README.API Documentation— Wiki page with the latest documentation. Past versions will be archived.Dfregex Syntax Informal Spec— Informal specification for what is considered valid Dfregex.Developer's Guide— Quick guidelines on contributing.Getting StartedInstall it from pypi by runningpipinstalldatetime-matcherThen, get it into your code by importing and instantiatingfromdatetime_matcherimportDatetimeMatcherdtm=DatetimeMatcher()Finally, run your data through it to perform subsitutions (or any of our many other supported operations!)oh_my_would_you_look_at_the_time=['TheWallClock_1982-Feb-27.jpeg','TheWristWatch_2003-Aug-11.jpg','TheSmartWatch_2020-Mar-10.jpeg',]pattern=r'(\w+)_%Y-%b-%d\.jpe?g'replace=r'%Y%m%d-\1.jpg'its_all_clear_now=dtm.sub(pattern,replace,text)fortextinoh_my_would_you_look_at_the_timeassertits_all_clear_now[0]=='19820227-TheWallClock.jpg'assertits_all_clear_now[1]=='20030811-TheWristWatch.jpg'assertits_all_clear_now[2]=='20200310-TheSmartWatch.jpg'ExampleUse Case in String Substitution with Datetime ReformattingLet's say we have several filenames of the following format that we want to rename:'MyLovelyPicture_2020-Mar-10.jpeg'We want to change them to look like this string:'20200310-MyLovelyPicture.jpg'The Unclean Way to Do It, without datetime-matcherUsing the standard libraryre.sub, we run into an issue:text='MyLovelyPicture_2020-Mar-10.jpeg'pattern=r'(\w+)_([0-9]{4}-\w{3}-[0-9]{2})\.jpe?g'# ❌ messyreplace=r'(??????)-\1.jpg'# ❌ what do we put for ??????result=re.sub(pattern,replace,text)# ❌ This does't workWe have to manually rundatetime.strptimewith a custom parser string to extract the
date, and then manually insert it back into the replacement string before running
a non-generic search-and-replace using the customized replacement string.Yuck.The Clean Way to Do It, with datetime-matcherWe can do the following for a quick and easy substitution with reformatting.fromdatetime_matcherimportDatetimeMatcherdtmatcher=DatetimeMatcher()text='MyLovelyPicture_2020-Mar-10.jpeg'pattern=r'(\w+)_%Y-%b-%d\.jpe?g'# ✅ regex + strptimereplace=r'%Y%m%d-\1.jpg'# ✅ template + strftimeresult=dtmatcher.sub(pattern,replace,text)# ✅ magical substitutionassertresult=='20200310-MyLovelyPicture.jpg'# ✅ This works like a charmDfregex Syntax Informal SpecThe syntax for dfregex is nearly identical to that of conventional python regex.
There is only one addition and one alteration to support datetime format codes.
This is far from a formal spec, but expect that currently supported syntaxes,
within the current major semantic version,
will NOT be removed unless provided reasonable notification and a generous deprecation period.The Datetime Format CodesThe percentage character indicates the beginning of a datetime format code. These codes
are the standard C-style ones used in the built-indatetimemodule forstrftime.For a list of standard codes, seethe Python docs.Minus the exceptions below, and barring platform-specific support,strftime.orgis a good alternative list.NOTE: The following codes are currentlynot supported:%Z,%c,%x,%XThe Percent Literal (%)The percentage literal in conventional regex (%) must be escaped in dfregex (\%)
because an unescaped one marks the beginning of a datetime format code and otherwise would be
ambiguous.DevelopmentThis project has an extensiveMakefilefor development automation. To get started quick: after cloning this project, runmake all. This should create a virtual environment, install all the required dev-time packages, lint, build, and test the project.Virtual Environment SetupYou only have to run these once. Andmake allcovers these steps automatically, but this is here for your reference.Usemake reinit-venvto create a new virtual environment from scratch. This will live inside the project's root. All subsequent make commands will automatically invoke python from inside this virtual environment. You may rerun this to completely wipe the virtual environment and start from scratch.Usemake init-piptoolsto bootstrap the virtual environment.Dependency ManagementTo add more runtime dependencies on pypi packages, add them torequirements.in. Then usemake install-requirementsto install them.To add more devtime dependencies (these will not be deemed dependencies in the distributable/built version of the package), add them to any*.infile within therequirements-devtime.d/directory. Then usemake install-requirementsto install them.To upgrade the pinned dependencies, runmake upgrade-requirements. This will re-resolve the requirements to the latest versions, pin the newly resolved versions, and install them.Buildingmake allis the one-stop shop for building the project. It will fix auto-fixable linting errors, raise any additional linting errors, build, run unit tests, and produce a coverage report.To only check lints or fix lints, usemake lintormake fix-lint.To only build, usemake build.To only test, usemake test.PublishingUsemake publish-testto publish to the test pypi repository.Usemake publishto publish to the prod repository.CleaningUsemake cleanto remove build artifacts.Usemake reinit-venvif you need to completely reset your virtual environment.