This is a tool for finding and replacing text without having to deal with complex Regex patterns. Only supports Windows 10 and 11 (not tested on other versions of Windows).
You need to have at least .NET 6 runtime installed to build the software. Download the latest runtime here. If you're not sure which one to download, try .NET 6.0 Version 6.0.16
In the project folder, run the below
dotnet publish -c Release -r win-x64 -p:PublishSingleFile=true -p:SelfContained=false
When that completes, go to \bin\Release\net<version>-windows\win-x64\publish and you'll find the RegexerUI.exe. Run it to use the software.
You can also just download the release builds if you don't wish to build manually.
If you wish to run the software without installing the required .NET runtime, download the self-contained release.
The text to search in should be entered in the Input textbox.
The structure of the text to search for is entered in the Find textbox. Use [[double braces]] to capture text for replacement, equivalent to Regex groups. The text within the double braces becomes the name of the captured group. This text must be made up of word characters i.e it should not contain symbols besides underscore (_).
The text that should replace captures is entered into the Replace textbox. You can use the names entered in the Find textbox here, and rewrite text surrounding it to change structure of each match in the input.
The Output textbox shows the result of the replacement.
When typing find or replace patterns, you have access to autocomplete suggestions once you're within a pattern i.e after entering [[. The suggestions don't automatically show up in areas where you can type freely e.g labels, separator texts, replacement texts, but you can press CTRL + SPACE to bring them up. If they still don't show up, it means the pattern so far is invalid and you should delete some characters until it shows up, or it means that you're not within a pattern.
You can import text files into the program with the Select input button and generated output can also be saved to a file with the Save output button. If you want to, for example, perform more operations on generated output, you can hit the Copy output to input button to copy the generated output to the input box. This is also useful for recursively running the same patterns on your input.
If you use the same find and replacement patterns often, you can save each find-replace pair as a template so you don't have to type them in each time you open the program. Click the Save template button and enter the name of the template in the dialog that pops up or select an existing template to overwrite. Templates are saved as text files in a folder called RegexerTemplates located in the same directory as the executable. In the program, you can delete templates with the Delete template button.
-
[[foo]]: This can capture a character, word, line or depending on what surrounds it. Translates to ([^\r\n]+?).
Example (characters)
//Input madam //Find [[foo]] //Replace [[foo]], //Output m,a,d,a,m,Example (words)
//Input (madam) //Find ([[foo]]) //Replace {[[foo]]} //Output {madam}Example (single lines)
//Input <tag> <content>Hello</content> </tag> //Find <tag> [[foo]] </tag> //Replace <new-tag> [[foo]] </new-tag> //Output <new-tag> <content>Hello</content> </new-tag> -
[[foo|<quantifier>]]: Three quantifiers are available to use with captures: Optional (o), greedy (g) and exact amount (<..>). The optional quantifier, used as [[foo|o]], means the capture may or may not appear in the match. Translates to ([^\r\n]+?)?. The greedy quantifier, used as [[foo|g]], will capture the most it can on the line it appears in. Translates to ([^\r\n]+). The exact amount quantifier, used as [[foo|]] or [[foo|]], will capture the specified number of characters. In the case of the second usage, maxAmount can be ommitted, in which case, it will work similar to greedy except it will capture at least minAmount characters. greedy and exact amount cannot be used together, but they can each be used with optional.
Example (greedy)
//Input madam //Find [[foo|g]] //Replace [[foo]], //Output madam,Example (optional)
//Input "madam." "tree. //huge and leafy" "mud." "well. //deep and wide" //Find "[[word]].[[comment|o]]" //Replace ([[word]]):[[comment]] //Output (madam): (tree): //huge and leafy (mud): (well): //deep and wideExample (exact amount)
//Input My number is 08160120004 //Find 0[[first|<3>]][[second|<3>]][[third|<4>]] //Replace (+234)-[[first]]-[[second]]-[[third]] //Output My number is (+234)-816-012-0004 -
[[foo|<restriction>]]: You can restrict your capture to word characters (w), digits (d) or whitespace (s). Translates to (\w+?), (\d+?) and ([^\S\r\n]+?) respectively. Each can be used with quantifiers e.g [[foo|so]] which translates to ([^\S\r\n]+?)?. You can only use one restriction in a capture.
Example
//Input Peter, 12. Drew!, 25. Judas, 30. Macon, . Linda, thirty. Bossa, 9. //Find [[name|w]], [[age|do]]. //Replace Name: [[name]], Age: [[age]] //Output Name: Peter, Age: 12 Drew!, 25. Name: Judas, Age: 30 Name: Macon, Age: Linda, thirty. Name: Bossa, Age: 9 -
[[foo|l]]: Use this to include new-line characters in the capture. In other words, make the match span multiple lines. Can be used with restriction and quantifiers. [[foo|l]] translates to ([\S\s]+?) and [[foo|wl]] translates to ([\w\r\n]+?).
Example
//Input names: { "Pete" "Abigail" "Tolani" } ages: { 45 18 23 } //Find [[key]]: {[[nums|dl]]} //Replace [[key]]:[[nums]] //Output names: { "Pete" "Abigail" "Tolani" } ages: 45 18 23 -
[[foo|ml]]: This captures one or more lines. Translates to ([^\r\n]*?)(\r\n(([^\S\r\n]*)[^\r\n]*?)?)*?. The difference between this and the include new-lines option ("l") is that each line captured using this can be modified in the replacement using prefixes or suffixes. Cannot be used with restrictions or quantifiers.
Example
//Input <tag> <content>Hello</content> <content>Hi</content> </tag> //Find <[[bar]]> [[foo|ml]] </[[lou]]> //Replace <new-[[bar]]> <p>[[foo|ml]]</p> </new-[[bar]]> //Output <new-tag> <p><content>Hello</content></p> <p><content>Hi</content></p> </new-tag> -
[[foo|m|separator|multiple-structured-text-to-capture]]: Use this to match multiple text with similar structure separated by the specified separator. The separator can be a regex pattern, and you can use to represent a line break. If the structured-text part is omitted, this will match whatever appears between the separators. You may also omit the name (i.e [[m||multiple-structured-text-to-capture]]) and it will be used for matching and not captured.
Example (with name)
//Input <input id="name" type="text" disabled="false" class="name"/> <input type="button" id="submit" class="big" max-length="5" disabled="true"/> //Find <input [[mul|m|{[\s<ml>]+}|[[key]]="[[value]]"]]/> //Replace <input [[mul|m:--:The key is [[key|m]], the value is [[value|m]]]]/> //Output <input The key is id, the value is name--The key is type, the value is text--The key is disabled, the value is false--The key is class, the value is name/> <input The key is type, the value is button--The key is id, the value is submit--The key is class, the value is big--The key is max-length, the value is 5--The key is disabled, the value is true/>Example (without name)
//Input <input id="name" type="text" disabled="false" class="name"/> <input type="button" id="submit" class="big" max-length="5" disabled="true"/> //Find <input [[m|{[\s<ml>]+}|[[key]]="[[value]]"]]/> //Replace <input Keys are [[key|m:, ]] and Values are [[value|m:, ]]/> //Output <input Keys are id, type, disabled, class and Values are name, text, false, name/> <input Keys are type, id, class, max-length, disabled and Values are button, submit, big, 5, true/> -
[[foo|u|phrase-or-line-to-capture]]: Use this to capture phrases (space-separated) or lines (new-line-separated) that can be optional and appear in any order. You may also omit the name (i.e [[u|phrase-or-line-to-match]]) and it will be used for matching and not captured. In the pattern, each phrase/line capture should appear on separate lines and should be adjacent to one another to represent a group.
Example (phrases)
//Input <input id="name" type="text" disabled class="name"/> <input type="button" id="submit" class="big" max-length="5" disabled/> //Find <input [[id|u|id="[[_id|w]]"]] [[class|u|class="[[_class|w]]"]] [[type|u|type="[[_type|w]]"]] [[length|u|max-length="[[_length|w]]"]] [[u|disabled]] /> //Replace <input [[id|u]] [[class|u]] [[type|u]] [[length|u]]/> //Output <input id="name" class="name" type="text"/> <input id="submit" class="big" type="button" max-length="5"/>Example (lines)
//Input saveUser( name: Peter, age: 12, gender: M, isEditing: false, status: alive ) saveUser( age: 9, gender: F, name: Bossa, isEditing: true, status: alive ) saveUser( name: Judas, age: 30, isEditing: false, status: alive ) saveUser( name: Paula, isEditing: true, status: alive ) //Find saveUser( [[name|u|name: [[userName]],]] [[age|u|age: [[userAge]],]] [[u|gender: M,]] [[u|gender: F,]] [[editing|u|isEditing: true,]] [[adding|u|isEditing: false,]] status: alive ) //Replace [[adding|u:addUser{]] [[editing|u:editUser{]] [[name|u:User's name is [[userName]]]] [[age|u:User's age is [[userAge]]]] [[userName]] is [[userAge]] years old } //Output addUser{ User's name is Peter User's age is 12 Peter is 12 years old } editUser{ User's name is Bossa User's age is 9 Bossa is 9 years old } addUser{ User's name is Judas User's age is 30 Judas is 30 years old } editUser{ User's name is Paula Paula is years old } -
[[foo{regex}]]: Use this to specify a custom regex pattern. You may also omit the name (i.e [[{regex}]]) and it will be used for matching and not captured.
Example
//Input Ade has 50 apples. Tolu had ten chairs, Bose had 70 oranges? Tayo1 has 30 bowls. Shola had 15 caps! //Find [[name{[a-zA-Z]+?}]] [[{(has|had)}]] [[{\d+}]] [[items{\w+}]][[{[.,?!]}]] //Replace -Name: [[name]] -Items: [[items]] //Output -Name: Ade -Items: apples Tolu had ten chairs, -Name: Bose -Items: oranges Tayo1 has 30 bowls. -Name: Shola -Items: caps
You can apply a few transformations to your match replacements, as described below:
-
Duplications: You can repeat a match multiple times in the output text with the replacement syntax [[foo|d:(number/expression):separator]]. The number represents the amount of duplications for the match. You can specify an expression instead of a number, and in this expression, you can use i, which represents the position of the match i.e if the match is the second one, i is 2. The only characters allowed in the expression are digits, +, -, /, * and % (modulo). Spaces are not allowed. The separator, which is optional, is the text that should appear between the duplications. If the separator isn't specified, the duplications are adjacent to each other (separated by nothing). To put each duplication in a separate line, use ml as the separator.
Example (basic)
//Input Tasty! //Find [[foo|g]] //Replace [[foo|d:5]] //Output Tasty!Tasty!Tasty!Tasty!Tasty!Example (separator)
//Input Tasty! //Find [[foo|g]] //Replace [[foo|d:5:...]] //Output Tasty!...Tasty!...Tasty!...Tasty!...Tasty!Example (expression)
//Input The soup was delicious! The porridge was sweet! The pap was tasty! //Find The [[food]] was [[adjective]]! //Replace The [[food]] was [[adjective|d:i]]! //Output The soup was delicious! The porridge was sweetsweet! The pap was tastytastytasty! -
Capitalizations: You can change the capitalization of a match to any of 3 supported types namely Upper case (u), Lower case (l), First letter upper case (fu), First letter lower case (fl) and Sentence case (s). The syntax is [[foo|c:(u/l/fu/fl/s)]].
Example
//Input peter went to school. jackson went to class. //Find [[name]] went to [[place]]. //Replace [[name|c:s]] went to [[place|c:u]]. //Output Peter went to SCHOOL. Jackson went to CLASS. -
Evaluations: You can replace a number match with an evaluation involving the number itself and/or the position of the match. The syntax is [[foo|e:expression]]. The expression works the same as in Duplications, except that in addition to i for using the match position, you also have m for using the match itself. This transform can only be used for matches restricted to digits i.e [[foo|d]]. An example of an expression is (m * 2) + i. In this example, if the match is 4, and its position is 2, the match is replaced with 10.
Example
//Input 1. Peter is 7 years old. 1. Tolani is 23 years old. 1. Adeolu is 12 years old. //Pattern [[sn|d]]. [[name]] is [[age|d]] years old. //Replace [[sn|e:i]]. [[name]] will be [[age|e:m+5]] years old in 5 years. //Output 1. Peter will be 12 years old in 5 years. 2. Tolani will be 28 years old in 5 years. 3. Adeolu will be 17 years old in 5 years. -
Conditional appearances: For optional matches ([[foo|o]]) and optional phrase/line capture ([[foo|u|phrase-or-line-to-capture]]), you can add text to the match depending on whether they are present. The syntax is [[foo|o:conditional_text]] or [[foo|u:conditional text]].
Example
//Input "madam." "tree. //huge and leafy" "mud." "well. //deep and wide" //Find "[[word]].[[comment|o]]" //Replace ([[comment|o:The ]][[word]][[comment|o: line had comments]]) //Output (madam) (The tree line had comments) (mud) (The well line had comments)