Custom text cleanup rules on Mac
You can do this with Note My, and here is how to write regex cleanup rules once, check what they will match before they run, and put the whole set over a document in a single pass.
Some mess arrives on a schedule. Copy from a styled document and you get control words and font fragments. Copy from a rendered web page and you get non-breaking spaces where ordinary spaces belong. Copy out of a chat window and you get zero-width characters wedged between words. If you run the same three find-and-replaces on every paste, write the patterns down once instead.
Note My keeps a user-editable list of regular-expression cleanup rules. You write them, count what they would match before you commit, run the whole set over a document as one undoable step, and export the set as JSON. This page covers all of it, from the first rule you write to the set you hand to a colleague.
Which Clean menu item you want
Start with the confusing part. The Clean pull-down in the toolbar — the wand glyph — offers two commands with similar names that do quite different jobs. Knowing which one you are reaching for saves a lot of guessing.
Choose between them by what you are cleaning. A known family of stray characters — invisible marks, unusual spaces, the wrong kind of separator — is category work, and the categories are already written for you. A mess with a shape only you can describe, the same three replacements on every paste from the same source, is rule work, and that is what this page is about.
| Our hidden-character scanner | Our cleanup rules | |
|---|---|---|
| What it covers | 21 fixed categories of stray character | Whatever regular expression you write |
| How you shape it | Tick the categories you want, or take one of four presets | Write any expression you like, and as many as you like |
| Where it acts | Skips strings and comments when you ask it to | Exactly where your pattern says, and nowhere else |
| Where you run it | Clean ▸ Clean Invisible / Special Characters… | Clean ▸ Clean Now |
| Where you configure it | Settings ▸ Text Cleanup | Clean ▸ Edit Removal Rules… |
The rest of this page is about the second column. If what you want is to strip invisible characters by category, with a findings table and a per-instance review, reach for our hidden-character scanner instead — a different job, covered on its own page.
The two give you different kinds of control. One hands you a tidy set of categories to tick; the other hands you the whole expressive range of a regular expression, which is worth writing tightly so it reaches exactly as far as you intend.
Open the Residual Removal Rules window
Click the Clean button in the toolbar and choose Edit Removal Rules…. The window that opens is titled Residual Removal Rules. It and Clean Now sit together in that one pull-down, a single click from the toolbar wherever you are in the document.
The window lists every rule with a checkbox, a name and a pattern. A filter field matches on both the name and the pattern, which is how you find one rule in a list you have let grow. Around it sit Add, Remove and Duplicate, Import… and Export…, Reset to Defaults, and Done. Nothing in your document changes while you sit in this window: editing the list is one step, sweeping the text is another, and you decide when the second one happens.
The eleven built-in rules
Eleven rules ship with the app. Eight are enabled from the start:
- RTF Control Words, RTF Group Braces and Font/Color Fragments — the debris left behind when styled text arrives as characters.
- NBSP→Space — a non-breaking space becomes an ordinary space.
- Zero-width chars, Soft hyphen and Word joiner — characters that occupy no width and quietly break searching, diffing and comparison.
- Line/Paragraph separators→Newline — the two Unicode separators some applications emit instead of a normal line break.
Three more are present but switched off by default: Narrow no-break space→Space, Figure space→Space, and Convert RTF→Plain Text, which turns styled text into plain text rather than swapping one string for another. The first two are characters typeset text sometimes uses on purpose, so replacing them stays a decision you make. Tick the checkbox when your material needs it.
The built-in patterns are maintained for you, so they stay current with the app while you get on with your own work. Everything around them is yours to set: whether a rule runs at all, and where it sits in the order. Duplicate one and the copy is yours outright, pattern, replacement, options and name all editable, which is the fastest way to bend a shipped pattern to a house style: take the RTF Control Words rule, duplicate it, tighten the copy to the exact debris your source produces, and switch the original off so only yours runs.
Write your own rule
-
Add the rule
Press Add for a new rule, or select something close to what you want and press Duplicate. Duplicating a built-in is the quickest way to get a working pattern you can adjust, and the copy is a normal editable rule.
Name it for the problem rather than the pattern. The name is one of the two fields the filter box searches, so a consistent prefix —
rtf:,export:— pays off later. -
Write the pattern
Patterns are ICU regular expressions. Character classes, quantifiers, alternation, groups and Unicode properties all behave as you would expect.
Keep each rule doing one thing. Two rules that can be enabled independently are far easier to diagnose than one clever pattern doing both jobs.
-
Set the replacement
The replacement is a template, not a literal string. Leave it empty and the match is deleted outright, which is what the zero-width and soft-hyphen built-ins do. Put a single space in it and every match collapses to a space, which is what the NBSP rule does.
-
Choose the options
Four options are set per rule, so one pattern can be case-insensitive while the next is not.
The four per-rule regular expression options Option Effect Case insensitive Letters match in either case. Anchors match lines ^and$match at every line boundary rather than only at the ends of the document.Dot matches line separators .also matches a newline, so a pattern can span lines.Allow comments and whitespace Whitespace inside the pattern is ignored and #starts a comment, so a long expression can be laid out readably. -
Leave it enabled, or park it
The checkbox governs whether the rule takes part in a sweep. A rule you need occasionally is better written once and left switched off than rewritten each time.
Test it before you run it
The window carries an Analyze panel, and it is why you can write rules here without holding your breath. Choose a scope of Document or Selection and it reports, per rule, how many times that rule matches. A status line gives the size of the scope, how many rules are enabled, the total matches, and an estimate of the replacements that would be made. Mistakes in a pattern are reported here too, so you find out at the moment you write one rather than after a sweep.
Counts refresh while you are still typing a pattern, so you can keep the panel open, adjust the expression a character at a time, and watch the numbers settle where you want them before anything touches the text. All of it happens on your Mac: nothing is uploaded, there is no account, and the document never leaves the machine.
Treat it as a dry run. Two readings deserve a pause: zero matches on a rule you have just written usually means the pattern is not matching what you think it is, and four thousand matches on a five-hundred-line file usually means it is far broader than you meant.
Select one representative paragraph in the editor first, then analyse in Selection scope. It is a much tighter feedback loop than analysing a whole file.
Order matters, and you control it
Rules run from the top of the list down, and each one works on the text the rule above it left behind. Drag a row to move it — a drop always lands above the row you release on — and the new order is remembered, so it is still there the next time you open the app.
So structural rules belong above cosmetic ones. If one rule converts a styled blob to plain text and another normalises non-breaking spaces, the conversion has to happen first or the second rule has nothing recognisable to work on. And if a rule that analyses correctly on its own does nothing in a full sweep, look at what is sitting above it.
Run the set with Clean Now
Choose Clean ▸ Clean Now. Every enabled rule runs, from the top of the list down, over the whole active document. You stay where you were: your place in the text is kept and the view does not jump.
It runs the moment you choose it. The Analyze panel is where you look before you leap — narrow to a selection there, read the counts, then let Clean Now put the finished set over the entire document in one go.
The whole sweep counts as one change, so a single ⌘Z reverses all of it at once instead of unpicking it match by match, and the Edit menu reads Undo Clean Residuals. That is the safety model: analyse, run, look at the result, undo if it is wrong.
Export and import a rule set as JSON
Press Export… to write the list out as JSON — the suggested filename is ResidualRules.json — and Import… to read one back in. That covers moving a set to a second Mac, keeping it in a repository beside the files it cleans, and handing a colleague the exact rules you used.
A rule set moves only when you move it. Nothing is synced on your behalf, and no account is involved.
Reset to Defaults restores the eleven built-ins to their shipped state and order, including the three that ship off. Export first if your own rules matter to you.
Troubleshooting
The pattern cell has turned red
The expression is not valid. Hover the cell and the tooltip carries the error. A rule in that state matches nothing and takes no part in a sweep. Your other rules still do their work, and the invalid one never applies half of itself, so a sweep can finish having changed less than you expected. Fix the pattern, watch its count come back in the Analyze panel, and sweep again.
Clean Now did nothing
Three ordinary causes. No rule is enabled, so tick the boxes. Nothing matched, which the Analyze panel in Document scope confirms in a second. Or the frontmost window has no document in it, in which case the command answers with a beep.
A rule reached into a string or a comment
Your rules go exactly where the pattern points, which is the whole appeal — and it means a broad pattern will find the same characters inside a quoted string as it does in prose. Narrow it by anchoring the expression or requiring some surrounding context, then confirm the new count in Selection scope over the passage in question. When you would rather have that judgement made for you, our hidden-character scanner carries a Protect authored text option built for precisely this.
Cleaning something you have just pasted
Reach for Clean Now straight after the paste: one click, and your whole enabled set goes over the document, undoable in one step like any other sweep.
I turned on "Clean pasted text" in Settings and got different results
That is a different switch, in Settings ▸ Text Cleanup, and it is off by default. It applies the default preset of our hidden-character scanner — Code-safe unless you changed it — to text you paste. Two settings, similar names, different jobs.
Getting your rules onto a colleague's Mac
Send them the JSON. Rules live with the app rather than inside the document, which keeps each person's set their own — opening a file you have cleaned never rearranges anybody else's list. Press Export…, send the file, and they press Import… to have your exact patterns, options and order in front of them.
Ways to get more out of a rule set
Once the list is written, it stops being a settings screen and starts being a tool you reach for. A few habits are worth picking up.
- Keep several jobs in one list. The checkboxes are the switch. Write the patterns for your styled-document imports, the ones for chat transcripts and the ones for a particular client's exports, prefix each group in its name, and tick the group you need before a sweep. The filter field brings a group into view in a keystroke or two.
- Survey before you sweep. Search ▸ Find in Folder… (⇧⌘F) searches a whole tree, so you can see which files a pattern turns up in across a project, then open the ones that need attention and run Clean Now on each.
- Use the right tool for a one-off. For a change you will make once and never again, our find and replace takes the same style of regular expression, and its Replace in All Files reaches every open tab in a single move. Save the rule list for the mess that keeps coming back.
- Let the counts be your preview. Analyze in Selection scope over one representative paragraph, watch the per-rule numbers settle, then run the set over the document knowing what to expect — and with one ⌘Z ready if you change your mind.
- Version the set. Export the JSON into the repository beside the files it cleans. The rules then travel with the project, and anyone joining is one Import… away from the same results you get.
Frequently asked questions
Where are my rules stored, and do they leave my Mac?
They stay on your Mac. Nothing is uploaded, there is no account to sign in to, and neither your rules nor the documents you run them over leave the machine. A rule set travels only as a JSON file you export deliberately and send yourself.
Can I refer to a capture group in the replacement?
The replacement is a template rather than a literal string, and an empty template deletes the match. Our find and replace takes the same kind of regular expression and the same style of template, where $1 stands for the first capture group — a useful place to prove a pattern on real text before you commit it to a rule.
Can I run just one rule instead of the whole set?
Yes — untick the others and Clean Now sweeps with just that one, which is a fair use of the checkboxes for a rule you are still getting to know. To try a pattern without touching the list at all, run it in our find and replace with Regular Expression ticked. Often the per-rule counts in the Analyze panel answer the question before you do either.
What is the difference between Clean Now and Clean Invisible / Special Characters…?
Clean Now runs your regular expressions and commits immediately. Clean Invisible / Special Characters… opens a review sheet for the 21 built-in categories, with a findings table of line and column, code point, category, action and risk, and an Apply button you press once you have looked.
Will a sweep break emoji or accented characters?
Your rules do exactly what you write, so match on the characters you actually mean and let the Analyze panel confirm the count before you sweep. When you would rather have that care taken for you, our hidden-character scanner keeps emoji families and accented characters whole while it works.
Can I undo a sweep after I have carried on typing?
Yes, though your later edits come off first, in the usual order. When you reach the sweep, one ⌘Z removes the whole of it rather than unwinding it match by match. Check the result before you save, because saving writes it to disk.