Repository: briannesbitt/Carbon (php)

Issue:
Translating ordinal words causing breaking change
<!--
    🛑 DON'T REMOVE ME.
    This issue template apply to all
      - bug reports,
      - feature proposals,
      - and documentation requests

    Having all those informations will allow us to know exactly
    what you expect and answer you faster and precisely (answer
    that matches your Carbon version, PHP version and usage).
    
    Note: Comments between <!- - and - -> won't appear in the final
    issue (See [Preview] tab).
-->
Hello,

I encountered an issue with the following code:
```php
Carbon::createFromLocaleFormat('d \d\e F \d\e Y', 'es', '05 de diciembre de 2022', 'America/Mexico_City');
```

Carbon version: **2.58.0**

PHP version: **8.1.13**

<!--
    Run the command `composer show nesbot/carbon`
    to get "versions"
    Use `echo phpversion();`
    to get PHP version.

    Some issues can depends on your context, settings,
    macros, timezone, language. So to be sure the code
    you give is enough to reproduce your bug, try it
    first in:
    https://play.phpsandbox.io/embed/nesbot/carbon?input=%3C%3Fphp%0A%0Aecho%20Carbon%3A%3Aparse('2018-06-01')-%3EsubDay()-%3Emonth%3B

    You can use the [Options] button to change the version
    then when you get the bug with this editor, you can use
    the [Export] button, copy the link of the opened tab,
    then paste it in the issue. Then we can immediatly get
    your issue.
-->


I expected to get:

```
No errors
```
<!--
    Always give your expectations. Each use has their owns.
    You may want daylight saving time to be taken into account,
    someone else want it to be ignored. You may want timezone
    to be used in comparisons, someone else may not, etc.
-->

But I actually get:

```
A textual month could not be found
Unexpected data found.
#0 /srv/app/vendor/nesbot/carbon/src/Carbon/Traits/Creator.php(865): Carbon\Carbon::rawCreateFromFormat()
```
[<!--
    If you did not succeed to get the same result in
    https://play.phpsandbox.io/embed/nesbot/carbon?input=%3C%3Fphp%0A%0Aecho%20Carbon%3A%3Aparse('2018-06-01')%3B then precise the
    result you get.
-->](https://play.phpsandbox.io/embed/nesbot/carbon?input=%3C%3Fphp%0A%0Aecho%20Carbon%3A%3Aparse(%272018-06-01%27)%3B)

Caused by https://github.com/briannesbitt/Carbon/pull/2693

Thanks!


Pull request:
Translate escaped word in `createFromLocaleFormat()`
Fix #2716

Patch:
diff --git a/src/Carbon/Traits/Creator.php b/src/Carbon/Traits/Creator.php
index be2c0f7c..1a6b78bf 100644
--- a/src/Carbon/Traits/Creator.php
+++ b/src/Carbon/Traits/Creator.php
@@ -862,6 +862,19 @@ trait Creator
      */
     public static function createFromLocaleFormat($format, $locale, $time, $tz = null)
     {
+        $format = preg_replace_callback(
+            '/(?:\\\\[a-zA-Z]|[bfkqCEJKQRV]){2,}/',
+            static function (array $match) use ($locale): string {
+                $word = str_replace('\\', '', $match[0]);
+                $translatedWord = static::translateTimeString($word, $locale, 'en');
+
+                return $word === $translatedWord
+                    ? $match[0]
+                    : preg_replace('/[a-zA-Z]/', '\\\\$0', $translatedWord);
+            },
+            $format
+        );
+
         return static::rawCreateFromFormat($format, static::translateTimeString($time, $locale, 'en'), $tz);
     }
 


Test patch:
diff --git a/tests/Carbon/CreateTest.php b/tests/Carbon/CreateTest.php
index 6f7a6d2e..b3d3c71e 100644
--- a/tests/Carbon/CreateTest.php
+++ b/tests/Carbon/CreateTest.php
@@ -350,6 +350,36 @@ class CreateTest extends AbstractTestCase
         $date = Carbon::createFromLocaleFormat('Y M d H,i,s', 'zh_TW', '2019 四月 4 12,04,21', 'Asia/Shanghai')->locale('zh');
 
         $this->assertSame('2019年4月4日星期四 中午 12点04分 Asia/Shanghai', $date->isoFormat('LLLL zz'));
+
+        $this->assertSame(
+            '2022-12-05 America/Mexico_City',
+            Carbon::createFromLocaleFormat('d * F * Y', 'es', '05 de diciembre de 2022', 'America/Mexico_City')
+                ->format('Y-m-d e')
+        );
+
+        $this->assertSame(
+            '2022-12-05 America/Mexico_City',
+            Carbon::createFromLocaleFormat('d \of F \of Y', 'es', '05 de diciembre de 2022', 'America/Mexico_City')
+                ->format('Y-m-d e')
+        );
+
+        $this->assertSame(
+            '2022-12-05 America/Mexico_City',
+            Carbon::createFromLocaleFormat('d \o\f F \o\f Y', 'es', '05 de diciembre de 2022', 'America/Mexico_City')
+                ->format('Y-m-d e')
+        );
+
+        $this->assertSame(
+            '2022-12-05 America/Mexico_City',
+            Carbon::createFromLocaleFormat('d \d\e F \d\e Y', 'es', '05 de diciembre de 2022', 'America/Mexico_City')
+                ->format('Y-m-d e')
+        );
+
+        $this->assertSame(
+            '2022-12-05 America/Mexico_City',
+            Carbon::createFromLocaleFormat('d \n\o\t F \n\o\t Y', 'es', '05 not diciembre not 2022', 'America/Mexico_City')
+                ->format('Y-m-d e')
+        );
     }
 
     public function testCreateFromIsoFormat()
diff --git a/tests/CarbonImmutable/CreateTest.php b/tests/CarbonImmutable/CreateTest.php
index d3385dc0..6620edd2 100644
--- a/tests/CarbonImmutable/CreateTest.php
+++ b/tests/CarbonImmutable/CreateTest.php
@@ -264,6 +264,36 @@ class CreateTest extends AbstractTestCase
         $date = Carbon::createFromLocaleFormat('Y M d H,i,s', 'zh_TW', '2019 四月 4 12,04,21', 'Asia/Shanghai')->locale('zh');
 
         $this->assertSame('2019年4月4日星期四 中午 12点04分 Asia/Shanghai', $date->isoFormat('LLLL zz'));
+
+        $this->assertSame(
+            '2022-12-05 America/Mexico_City',
+            Carbon::createFromLocaleFormat('d * F * Y', 'es', '05 de diciembre de 2022', 'America/Mexico_City')
+                ->format('Y-m-d e')
+        );
+
+        $this->assertSame(
+            '2022-12-05 America/Mexico_City',
+            Carbon::createFromLocaleFormat('d \of F \of Y', 'es', '05 de diciembre de 2022', 'America/Mexico_City')
+                ->format('Y-m-d e')
+        );
+
+        $this->assertSame(
+            '2022-12-05 America/Mexico_City',
+            Carbon::createFromLocaleFormat('d \o\f F \o\f Y', 'es', '05 de diciembre de 2022', 'America/Mexico_City')
+                ->format('Y-m-d e')
+        );
+
+        $this->assertSame(
+            '2022-12-05 America/Mexico_City',
+            Carbon::createFromLocaleFormat('d \d\e F \d\e Y', 'es', '05 de diciembre de 2022', 'America/Mexico_City')
+                ->format('Y-m-d e')
+        );
+
+        $this->assertSame(
+            '2022-12-05 America/Mexico_City',
+            Carbon::createFromLocaleFormat('d \n\o\t F \n\o\t Y', 'es', '05 not diciembre not 2022', 'America/Mexico_City')
+                ->format('Y-m-d e')
+        );
     }
 
     public function testCreateFromIsoFormat()