Repository: SubtitleEdit/subtitleedit (2026-03-25T09:59:41Z)

Issue:
[beta10] OCR retults are broken when containing "
When OCRing VobSub subtitles with PaddleOCR Standalone, lines containing a double quote (`"`) seem to be parsed incorrectly.
More specifically, apostrophes (`'`) after the quote are escaped and become `\'`.

Example:
`" It's raining...`
becomes:
`" It\'s raining...`

I am not sure how this behaves when the line contains two double quotes. I can't find a good sub to test it. 

This may be caused by PaddleOCR using a different string representation when a double quote is present, which Subtitle Edit may not be parsing correctly.

I'm on Windows, if that helps.


Discussion:
Fixed in newest pr https://github.com/SubtitleEdit/subtitleedit/pull/10419



Patch:
diff --git a/src/UI/Features/Ocr/Engines/PaddleOcrResultParser.cs b/src/UI/Features/Ocr/Engines/PaddleOcrResultParser.cs
index 3a8cce6e3af..922d78b5a28 100644
--- a/src/UI/Features/Ocr/Engines/PaddleOcrResultParser.cs
+++ b/src/UI/Features/Ocr/Engines/PaddleOcrResultParser.cs
@@ -66,7 +66,9 @@ public TextDetectionResult Parse(string input)
     {
         // Extract text using regex
         var textMatch = Regex.Match(input, @"\([""'](.*)[""'],");
-        var text = textMatch.Groups[1].Value;
+        var text = textMatch.Groups[1].Value
+            .Replace("\\'", "'")
+            .Replace("\\\"", "\"");
 
         // Extract confidence using regex
         input = input.Replace(" ", string.Empty);


Test patch:
diff --git a/tests/UI/Features/Ocr/Engines/PaddleOcrResultParserTests.cs b/tests/UI/Features/Ocr/Engines/PaddleOcrResultParserTests.cs
new file mode 100644
index 00000000000..889145ee241
--- /dev/null
+++ b/tests/UI/Features/Ocr/Engines/PaddleOcrResultParserTests.cs
@@ -0,0 +1,53 @@
+using Nikse.SubtitleEdit.Features.Ocr;
+
+namespace UITests.Features.Ocr.Engines;
+
+public class PaddleOcrResultParserTests
+{
+    private readonly PaddleOcrResultParser _parser = new();
+
+    private static string MakeLine(string pythonText, double confidence = 0.99) =>
+        $"[[[100.0, 200.0], [300.0, 200.0], [300.0, 250.0], [100.0, 250.0]], ('{pythonText}', {confidence.ToString(System.Globalization.CultureInfo.InvariantCulture)})]";
+
+    [Fact]
+    public void Parse_NormalText_ReturnsText()
+    {
+        var result = _parser.Parse(MakeLine("Hello world"));
+        Assert.Equal("Hello world", result.Text);
+    }
+
+    [Fact]
+    public void Parse_TextWithEscapedApostrophe_UnescapesApostrophe()
+    {
+        // Python repr wraps in single quotes and escapes inner apostrophes when text starts with "
+        var input = "[[[100.0, 200.0], [300.0, 200.0], [300.0, 250.0], [100.0, 250.0]], ('\" It\\'s raining...', 0.99)]";
+        var result = _parser.Parse(input);
+        Assert.Equal("\" It's raining...", result.Text);
+    }
+
+    [Fact]
+    public void Parse_TextWithDoubleQuoteWrappedInSingleQuotes_ReturnsText()
+    {
+        // Python: 'He said "hello"'
+        var input = "[[[100.0, 200.0], [300.0, 200.0], [300.0, 250.0], [100.0, 250.0]], ('He said \"hello\"', 0.99)]";
+        var result = _parser.Parse(input);
+        Assert.Equal("He said \"hello\"", result.Text);
+    }
+
+    [Fact]
+    public void Parse_ConfidenceValue_ParsedCorrectly()
+    {
+        var result = _parser.Parse(MakeLine("Test", 0.9753));
+        Assert.Equal(0.9753, result.Confidence, precision: 4);
+    }
+
+    [Fact]
+    public void Parse_BoundingBox_ParsedCorrectly()
+    {
+        var result = _parser.Parse(MakeLine("Test"));
+        Assert.Equal(100.0, result.BoundingBox.TopLeft.X);
+        Assert.Equal(200.0, result.BoundingBox.TopLeft.Y);
+        Assert.Equal(300.0, result.BoundingBox.TopRight.X);
+        Assert.Equal(250.0, result.BoundingBox.BottomLeft.Y);
+    }
+}