Improve the formatting of strings that contain unprintable ASCII characters.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1e9e16d..f9bc5cb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.11.4+2
+
+* Improve the formatting of strings that contain unprintable ASCII characters.
+
 ## 0.11.4+1
 
 * Correctly match and print `String`s containing characters that must be
diff --git a/lib/src/util.dart b/lib/src/util.dart
index a99d2dd..8706009 100644
--- a/lib/src/util.dart
+++ b/lib/src/util.dart
@@ -15,11 +15,12 @@
   '\b': r'\b',
   '\t': r'\t',
   '\v': r'\v',
+  '\x7F': r'\x7F', // delete
 };
 
 /// A [RegExp] that matches whitespace characters that should be escaped.
-final _escapeRegExp =
-    new RegExp("[${_escapeMap.keys.map(_getHexLiteral).join()}]");
+final _escapeRegExp = new RegExp(
+    "[\\x00-\\x07\\x0E-\\x1F${_escapeMap.keys.map(_getHexLiteral).join()}]");
 
 /// Useful utility for nesting match states.
 void addStateInfo(Map matchState, Map values) {
@@ -51,12 +52,14 @@
 String escape(String str) {
   str = str.replaceAll('\\', r'\\');
   return str.replaceAllMapped(_escapeRegExp, (match) {
-    return _escapeMap[match[0]];
+    var mapped = _escapeMap[match[0]];
+    if (mapped != null) return mapped;
+    return _getHexLiteral(match[0]);
   });
 }
 
 /// Given single-character string, return the hex-escaped equivalent.
 String _getHexLiteral(String input) {
   int rune = input.runes.single;
-  return r'\x' + rune.toRadixString(16).padLeft(2, '0');
+  return r'\x' + rune.toRadixString(16).toUpperCase().padLeft(2, '0');
 }
diff --git a/pubspec.yaml b/pubspec.yaml
index 3988f16..f96cb1c 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: matcher
-version: 0.11.4+1
+version: 0.11.4+2
 author: Dart Team <misc@dartlang.org>
 description: Support for specifying test expectations
 homepage: https://github.com/dart-lang/matcher
diff --git a/test/escape_test.dart b/test/escape_test.dart
index 035967c..db1a7a8 100644
--- a/test/escape_test.dart
+++ b/test/escape_test.dart
@@ -16,12 +16,17 @@
     _testEscaping('backspace', '\b', r'\b');
     _testEscaping('tab', '\t', r'\t');
     _testEscaping('vertical tab', '\v', r'\v');
+    _testEscaping('null byte', '\x00', r'\x00');
+    _testEscaping('ASCII control character', '\x11', r'\x11');
+    _testEscaping('delete', '\x7F', r'\x7F');
     _testEscaping('escape combos', r'\n', r'\\n');
     _testEscaping('All characters',
         'A new line\nA charriage return\rA form feed\fA backspace\b'
-        'A tab\tA vertical tab\vA slash\\',
+        'A tab\tA vertical tab\vA slash\\A null byte\x00A control char\x1D'
+        'A delete\x7F',
         r'A new line\nA charriage return\rA form feed\fA backspace\b'
-        r'A tab\tA vertical tab\vA slash\\');
+        r'A tab\tA vertical tab\vA slash\\A null byte\x00A control char\x1D'
+        r'A delete\x7F');
   });
 
   group('unequal strings remain unequal when escaped', () {