diff --git a/schema/__init__.py b/schema/__init__.py
index 31bd71b..346e367 100644
--- a/schema/__init__.py
+++ b/schema/__init__.py
@@ -590,6 +590,7 @@ def json_schema(
         def _json_schema(
             schema: "Schema",
             is_main_schema: bool = True,
+            title: Union[str, None] = None,
             description: Union[str, None] = None,
             allow_reference: bool = True,
         ) -> Dict[str, Any]:
@@ -654,6 +655,8 @@ def _to_schema(s: Any, ignore_extra_keys: bool) -> Schema:
             return_description: Union[str, None] = description or schema.description
             if return_description:
                 return_schema["description"] = return_description
+            if title:
+                return_schema["title"] = title
 
             # Check if we have to create a common definition and use as reference
             if allow_reference and schema.as_reference:
@@ -696,7 +699,11 @@ def _to_schema(s: Any, ignore_extra_keys: bool) -> Schema:
                         ]
                         # All values are simple, can use enum or const
                         if len(or_values) == 1:
-                            return_schema["const"] = _to_json_type(or_values[0])
+                            or_value = or_values[0]
+                            if or_value is None:
+                                return_schema["type"] = None
+                            else:
+                                return_schema["const"] = _to_json_type(or_value)
                             return return_schema
                         return_schema["enum"] = or_values
                     else:
@@ -728,10 +735,17 @@ def _to_schema(s: Any, ignore_extra_keys: bool) -> Schema:
                     else:
                         return_schema["allOf"] = all_of_values
                 elif flavor == COMPARABLE:
-                    return_schema["const"] = _to_json_type(s)
+                    if s is None:
+                        return_schema["type"] = None
+                    else:
+                        return_schema["const"] = _to_json_type(s)
                 elif flavor == VALIDATOR and type(s) == Regex:
                     return_schema["type"] = "string"
-                    return_schema["pattern"] = s.pattern_str
+                    # JSON schema uses ECMAScript regex syntax
+                    # Translating one to another is not easy, but this should work for simple cases
+                    return_schema["pattern"] = re.sub(
+                        r"\(\?P<[a-z\d_]+>", "(", s.pattern_str
+                    ).replace("/", r"\/")
                 else:
                     if flavor != DICT:
                         # If not handled, do not check
@@ -753,6 +767,16 @@ def _key_allows_additional_properties(key: Any) -> bool:
 
                             return key == str or key == object
 
+                        def _get_key_title(key: Any) -> Union[str, None]:
+                            """Get the title associated to a key (as specified in a Literal object). Return None if not a Literal"""
+                            if isinstance(key, Optional):
+                                return _get_key_title(key.schema)
+
+                            if isinstance(key, Literal):
+                                return key.title
+
+                            return None
+
                         def _get_key_description(key: Any) -> Union[str, None]:
                             """Get the description associated to a key (as specified in a Literal object). Return None if not a Literal"""
                             if isinstance(key, Optional):
@@ -786,6 +810,7 @@ def _get_key_name(key: Any) -> Any:
                             expanded_schema[key_name] = _json_schema(
                                 sub_schema,
                                 is_main_schema=False,
+                                title=_get_key_title(key),
                                 description=_get_key_description(key),
                             )
                             if isinstance(key, Optional) and hasattr(key, "default"):
@@ -888,9 +913,15 @@ def _default_function(nkey: Any, data: Any, error: Any) -> NoReturn:
 
 
 class Literal:
-    def __init__(self, value: Any, description: Union[str, None] = None) -> None:
+    def __init__(
+        self,
+        value: Any,
+        description: Union[str, None] = None,
+        title: Union[str, None] = None,
+    ) -> None:
         self._schema: Any = value
         self._description: Union[str, None] = description
+        self._title: Union[str, None] = title
 
     def __str__(self) -> str:
         return str(self._schema)
@@ -902,6 +933,10 @@ def __repr__(self) -> str:
     def description(self) -> Union[str, None]:
         return self._description
 
+    @property
+    def title(self) -> Union[str, None]:
+        return self._title
+
     @property
     def schema(self) -> Any:
         return self._schema
diff --git a/test_schema.py b/test_schema.py
index 2d7a495..a129aed 100644
--- a/test_schema.py
+++ b/test_schema.py
@@ -1078,6 +1078,20 @@ def test_json_schema_regex():
     }
 
 
+def test_json_schema_ecma_compliant_regex():
+    s = Schema({Optional("username"): Regex("^(?P<name>[a-zA-Z_][a-zA-Z0-9_]*)/$")})
+    assert s.json_schema("my-id") == {
+        "$schema": "http://json-schema.org/draft-07/schema#",
+        "$id": "my-id",
+        "properties": {
+            "username": {"type": "string", "pattern": "^([a-zA-Z_][a-zA-Z0-9_]*)\/$"}
+        },
+        "required": [],
+        "additionalProperties": False,
+        "type": "object",
+    }
+
+
 def test_json_schema_or_types():
     s = Schema({"test": Or(str, int)})
     assert s.json_schema("my-id") == {
@@ -1132,7 +1146,7 @@ def test_json_schema_const_is_none():
     assert s.json_schema("my-id") == {
         "$schema": "http://json-schema.org/draft-07/schema#",
         "$id": "my-id",
-        "properties": {"test": {"const": None}},
+        "properties": {"test": {"type": None}},
         "required": ["test"],
         "additionalProperties": False,
         "type": "object",
@@ -1399,9 +1413,15 @@ def test_json_schema_dict_type():
     }
 
 
-def test_json_schema_title_and_description():
+def test_regex_json_schema():
     s = Schema(
-        {Literal("productId", description="The unique identifier for a product"): int},
+        {
+            Literal(
+                "productId",
+                title="Product ID",
+                description="The unique identifier for a product",
+            ): int
+        },
         name="Product",
         description="A product in the catalog",
     )
@@ -1412,6 +1432,7 @@ def test_json_schema_title_and_description():
         "description": "A product in the catalog",
         "properties": {
             "productId": {
+                "title": "Product ID",
                 "description": "The unique identifier for a product",
                 "type": "integer",
             }