diff --git a/src/Nager.PublicSuffix.UnitTest/TldRuleExtensionsTests.cs b/src/Nager.PublicSuffix.UnitTest/TldRuleExtensionsTests.cs
new file mode 100644
index 0000000..04b1216
--- /dev/null
+++ b/src/Nager.PublicSuffix.UnitTest/TldRuleExtensionsTests.cs
@@ -0,0 +1,57 @@
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Nager.PublicSuffix.Extensions;
+using Nager.PublicSuffix.Models;
+using Nager.PublicSuffix.RuleParsers;
+
+namespace Nager.PublicSuffix.UnitTest;
+
+[TestClass]
+public class TldRuleExtensionsTests
+{
+ [TestMethod]
+ public void UnparseWithExceptionTest()
+ {
+ const string rulesInText = """
+ foo.com
+ !bar.com
+ !foo.bar.com
+ """;
+
+ var (rules1, rules2) = ParseUnparseRules(rulesInText);
+
+ CollectionAssert.AreEqual(rules1, rules2);
+ Assert.AreEqual(TldRuleType.WildcardException, rules2[1].Type);
+ }
+
+ [TestMethod]
+ public void UnparseWithWildCardTest()
+ {
+ const string rulesInText = """
+ natal.br
+ net.br
+ niteroi.br
+ *.nom.br
+ not.br
+ ntr.br
+ odo.br
+ ong.br
+ org.br
+ """;
+ var (rules1, rules2) = ParseUnparseRules(rulesInText);
+
+ CollectionAssert.AreEqual(rules1, rules2);
+ Assert.AreEqual(TldRuleType.Wildcard, rules2[3].Type);
+ }
+
+ private static (TldRule[] rules1, TldRule[] rules2) ParseUnparseRules(string rulesText)
+ {
+ var ruleParser = new TldRuleParser();
+
+ var rules1 = ruleParser.ParseRules(rulesText).ToArray();
+ var rulesUnParsedText = rules1.UnparseRules();
+ var rules2 = ruleParser.ParseRules(rulesUnParsedText).ToArray();
+
+ return (rules1, rules2);
+ }
+}
diff --git a/src/Nager.PublicSuffix/Extensions/TldRuleExtensions.cs b/src/Nager.PublicSuffix/Extensions/TldRuleExtensions.cs
new file mode 100644
index 0000000..5a164a6
--- /dev/null
+++ b/src/Nager.PublicSuffix/Extensions/TldRuleExtensions.cs
@@ -0,0 +1,57 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Nager.PublicSuffix.Models;
+
+namespace Nager.PublicSuffix.Extensions
+{
+ ///
+ /// TldRule Extensions
+ ///
+ public static class TldRuleExtensions
+ {
+ ///
+ /// Converts the collection of to text.
+ ///
+ /// The collection of rules
+ ///
+ public static string UnparseRules(this IEnumerable rules)
+ {
+ var rulesData = new StringBuilder();
+ foreach (var division in rules.GroupBy(rule => rule.Division))
+ {
+ switch (division.Key)
+ {
+ case TldRuleDivision.ICANN:
+ rulesData.Append("\n// ===BEGIN ICANN DOMAINS===\n");
+ break;
+ case TldRuleDivision.Private:
+ rulesData.Append("\n// ===BEGIN PRIVATE DOMAINS===\n");
+ break;
+ }
+
+ foreach (var rule in division)
+ {
+ rulesData.Append("\n");
+
+ if (rule.Type == TldRuleType.WildcardException)
+ {
+ rulesData.Append("!");
+ }
+ rulesData.Append(rule.Name);
+ }
+
+ switch (division.Key)
+ {
+ case TldRuleDivision.ICANN:
+ rulesData.Append("\n// ===END ICANN DOMAINS===\n");
+ break;
+ case TldRuleDivision.Private:
+ rulesData.Append("\n// ===END PRIVATE DOMAINS===\n");
+ break;
+ }
+ }
+
+ return rulesData.ToString();
+ }
+ }}
\ No newline at end of file