Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Here is a regex that works for React and Preact JSX/TSX "class" and "className" with + without brackets =) #85

Open
GavinRay97 opened this issue Jul 11, 2020 · 7 comments
Labels
documentation Improvements or additions to documentation

Comments

@GavinRay97
Copy link
Contributor

Had a friend who writes React ask about this and helped him figure out a working regex, here it is:

"headwind.classRegex": {
  "javascriptreact": "(?:\\b(?:class|className)?\\s*=\\s*{?[\\\"\\']([_a-zA-Z0-9\\s\\-\\:/]+)[\\\"\\']}?)",
  "typescriptreact": "(?:\\b(?:class|className)?\\s*=\\s*{?[\\\"\\']([_a-zA-Z0-9\\s\\-\\:/]+)[\\\"\\']}?)"
}

headwind-regex

@aeonthread
Copy link

@GavinRay97 this solved my problem thank you

@heybourn heybourn added the documentation Improvements or additions to documentation label Jul 13, 2020
@jlarmstrongiv
Copy link

And for twin.macro while we’re at it:

{
  "headwind.classRegex": {
    "typescriptreact": "(?:\\b(?:class|className|tw)?\\.?\\w?\\s*=*\\s*{?[\\\"\\'\\`]([_a-zA-Z0-9\\s\\-\\:/]+)[\\\"\\'\\`]}?)",
    "javascriptreact": "(?:\\b(?:class|className|tw)?\\.?\\w?\\s*=*\\s*{?[\\\"\\'\\`]([_a-zA-Z0-9\\s\\-\\:/]+)[\\\"\\'\\`]}?)"
  }
}

The debugging example in the README is super helpful and the only thing after that is escaping the regex.

@j0hnm4r5
Copy link

Here's a slightly more full-featured regex for twin.macro:

"headwind.classRegex": {
	"javascript": "(?:\\b(?:class|className|tw)(?:=(?:{\\s*)?)?(?:\\.\\w*)?(?:\\(\\s*\\w*\\s*\\))?[\\\"\\'\\`]([\\w\\s\\-\\:\\[\\]]+)[\\\"\\'\\`]}?)",
	"javascriptreact": "(?:\\b(?:class|className|tw)(?:=(?:{\\s*)?)?(?:\\.\\w*)?(?:\\(\\s*\\w*\\s*\\))?[\\\"\\'\\`]([\\w\\s\\-\\:\\[\\]]+)[\\\"\\'\\`]}?)",
	"typescript": "(?:\\b(?:class|className|tw)(?:=(?:{\\s*)?)?(?:\\.\\w*)?(?:\\(\\s*\\w*\\s*\\))?[\\\"\\'\\`]([\\w\\s\\-\\:\\[\\]]+)[\\\"\\'\\`]}?)",
	"typescriptreact": "(?:\\b(?:class|className|tw)(?:=(?:{\\s*)?)?(?:\\.\\w*)?(?:\\(\\s*\\w*\\s*\\))?[\\\"\\'\\`]([\\w\\s\\-\\:\\[\\]]+)[\\\"\\'\\`]}?)"
},

I'm new to regex, so I just want to break it down (more for my sanity that anything else):

  • (?:) is a non-capturing group, which means it should attempt to match the contents, but not return them.
  • (?:class|className|tw) matches class, className, or tw.
  • (?:=(?:{\s*)?)? optionally matches an = followed by an optional { followed by optional whitespace (i.e., tw={ or - tw={ ).
  • (?:\.\w*)? optionally matches a . followed by any number of letters (i.e., tw.div).
  • (?:\(\s*\w*\s*\))? optionally matches a ( followed by optional whitespace then any number of letters then more optional whitespace and a ) (i.e., tw(div) or tw( div )).
  • [\"\'\`] matches a ", ', or `.
  • ([\w\s\-\:\[\]]+) matches any number of letters, whitespace, hyphens, and square brackets (i.e., all of the tailwind classes) and returns them.
  • }? optionally matches the closing } when that's needed.

@bbugh
Copy link

bbugh commented Jun 21, 2021

That regex is wonderful, thank you @j0hnm4r5! But there's a few problems with it:

  • it doesn't work for interpolated strings
  • it doesn't support slashes like h-1/2
  • it doesn't support dash prefixes like -top-0.5
  • it doesn't support periods like right-1.5

Here's one that fixes these issues:

  "headwind.classRegex": {
    "javascript": "(?:\\b(?:class|className|tw)(?:=(?:{\\s*)?)?(?:\\.\\w*)?(?:\\(\\s*\\w*\\s*\\))?[\\\"\\'\\`]((?:[\\w\\s\\-\\/\\:\\.\\[\\]]|\\$\\{(.*?)\\})+)[\\\"\\'\\`]}?)",
    "javascriptreact": "(?:\\b(?:class|className|tw)(?:=(?:{\\s*)?)?(?:\\.\\w*)?(?:\\(\\s*\\w*\\s*\\))?[\\\"\\'\\`]((?:[\\w\\s\\-\\/\\:\\.\\[\\]]|\\$\\{(.*?)\\})+)[\\\"\\'\\`]}?)",
    "typescript": "(?:\\b(?:class|className|tw)(?:=(?:{\\s*)?)?(?:\\.\\w*)?(?:\\(\\s*\\w*\\s*\\))?[\\\"\\'\\`]((?:[\\w\\s\\-\\/\\:\\.\\[\\]]|\\$\\{(.*?)\\})+)[\\\"\\'\\`]}?)",
    "typescriptreact": "(?:\\b(?:class|className|tw)(?:=(?:{\\s*)?)?(?:\\.\\w*)?(?:\\(\\s*\\w*\\s*\\))?[\\\"\\'\\`]((?:[\\w\\s\\-\\/\\:\\.\\[\\]]|\\$\\{(.*?)\\})+)[\\\"\\'\\`]}?)"
  },

Here is the regexr for the new regex with all passing tests:

@KnifeFed
Copy link

KnifeFed commented Oct 19, 2021

^ Does this regex sort JIT mode correctly, e.g. w-[10px]?

@bbugh
Copy link

bbugh commented Jun 15, 2022

@valflrt
Copy link

valflrt commented Jan 8, 2023

Thank you so much for your regex @bbugh.
I'm not a regexpert (aha) but something is missing in your regex:

When some tailwind classes are set as important, the regex doesn't work... (I'm working on tsx files)

Example:

<div className={"!class1 !class2 ..."}></div>

Hope you could fix it !
Thank you again :)

Edit: I think I fixed it myself:

- (?:\b(?:class|className|tw)(?:=(?:{\s*)?)?(?:\.\w*)?(?:\(\s*\w*\s*\))?[\"\'\`]((?:[\w\s\-\/\:\.\[\]]|\$\{(.*?)\})+)[\"\'\`]}?)
+ (?:\b(?:class|className|tw)(?:=(?:{\s*)?)?(?:\.\w*)?(?:\(\s*\w*\s*\))?[\"\'\`]((?:[\w\s\-\/\:\.\[\]]\!?|\$\{(.*?)\}))+[\"\'\`]}?)
  "headwind.classRegex": {
    "javascript": "/(?:\\b(?:class|className|tw)(?:=(?:{\\s*)?)?(?:\\.\\w*)?(?:\\(\\s*\\w*\\s*\\))?[\\\"\\'\\`]((?:[\\w\\s\\-\\/\\:\\.\\[\\]]\\!?|\\$\\{(.*?)\\}))+[\\\"\\'\\`]}?)/",
    "javascriptreact": "/(?:\\b(?:class|className|tw)(?:=(?:{\\s*)?)?(?:\\.\\w*)?(?:\\(\\s*\\w*\\s*\\))?[\\\"\\'\\`]((?:[\\w\\s\\-\\/\\:\\.\\[\\]]\\!?|\\$\\{(.*?)\\}))+[\\\"\\'\\`]}?)/",
    "typescript": "/(?:\\b(?:class|className|tw)(?:=(?:{\\s*)?)?(?:\\.\\w*)?(?:\\(\\s*\\w*\\s*\\))?[\\\"\\'\\`]((?:[\\w\\s\\-\\/\\:\\.\\[\\]]\\!?|\\$\\{(.*?)\\}))+[\\\"\\'\\`]}?)/",
    "typescriptreact": "/(?:\\b(?:class|className|tw)(?:=(?:{\\s*)?)?(?:\\.\\w*)?(?:\\(\\s*\\w*\\s*\\))?[\\\"\\'\\`]((?:[\\w\\s\\-\\/\\:\\.\\[\\]]\\!?|\\$\\{(.*?)\\}))+[\\\"\\'\\`]}?)/"
  },

Edit 2: I think it doesn't work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

8 participants