حالة طرفية في Postgres لا تتبع قواعد التعبير العادي POSIX؟

مرحباً، أحاول تشغيل بعض أوامر regexp_replace في وحدة تحكم pg لتحويل الروابط في مثيل Discourse التجريبي الخاص بي الذي تم ترحيله من منتدى Drupal 7 ضخم. عبر ما يقرب من 2 مليون مشاركة، هناك مجموعة من الروابط بتنسيق Textile تحتاج إلى تحويلها إلى Markdown. هذا ما أحاول استخدامه:

إنه يعمل بشكل صحيح في المختبر أعلاه وكذلك في محرر النصوص الخاص بي؛ إنه يحول هذا:

  • Cqwertyuioy - Lasgfdf Sddgfdds (Dsajjsa Vsjsjk Osaskgkk Spfs) \"link\":http://www.youtube.com/watch?v=aQjkOmzQ8RT

إلى هذا:

  • Cqwertyuioy - Lasgfdf Sddgfdds (Dsajjsa Vsjsjk Osaskgkk Spfs) [link](http://www.youtube.com/watch?v=aQjkOmzQ8RT)

ولكن في وحدة تحكم pg الخاصة بـ Discourse، أقوم بتشغيل هذا:

  • update posts set raw = regexp_replace(raw, '\"(.*?)\"\\:(http\\S+?(?=\\W+(?:$|\\s))|http\\S+)', E'[\\\\1](\\\\2)', 'g');

وأحصل على هذا:

  • Cqwertyuioy - Lasgfdf Sddgfdds (Dsajjsa Vsjsjk Osaskgkk Spfs) [link](http:)//www.youtube.com/watch?v=aQjkOmzQ8RT

(آسف على إخفاء الهوية.) لذا فإن الجزء المهم هو:

  • صحيح: [link](http://www.youtube.com/watch?v=aQjkOmzQ8RT)
  • خاطئ: [link](http:)//www.youtube.com/watch?v=aQjkOmzQ8RT

أتخيل أن الأمر يتعلق بغرابة حرف الهروب في حالة استعلامات SQL و/أو الوظائف الخاصة لـ [] و () مقابل الحرفي، لكنني لا أستطيع معرفة ذلك. أي أفكار؟ شكراً!

لا أعرف PostgreSQL، ولكنه يعمل باستخدام وحدة تحكم rails:

Post.find_each do |p|
  p.raw.gsub!(/\"(.*?)\"\\:(http\\S+?(?=\\W+(?:$|\\s))|http\\S+)/, '[\\\\1](\\\\2)')
  p.save
end
إعجابَين (2)

آه، شكراً جزيلاً على إرشادي لكيفية استخدام وحدة تحكم Rails لذلك. يبدو أنها أبطأ بكثير من تشغيل أمر SQL خام (وهو أمر منطقي)، لذا سأبلغ عن ذلك إذا/عندما ينتهي الأمر.

حسنًا، لقد أنهيت عملية Rails وعدت إلى وحدة تحكم pg. تلقيت أيضًا اقتراحًا للتعبير العادي أبسط بكثير (ويؤمل أن يكون أسهل في تصحيح الأخطاء) ويعمل بشكل جيد جدًا خارج وحدة تحكم pg:
" (.*?) ": (\S*)\b

ولكن هناك بالتأكيد شيء غير قياسي في استعلام SQL، لم يؤثر هذا على الروابط على الإطلاق:
update posts set raw = regexp_replace(raw, '\"(.*?)\":(\\S*)\\b', E'[\\\\1](\\\\2)', 'g');
ولا هذا:
update posts set raw = regexp_replace(raw, '\"(.*?)\"\\:(\\S*)\\b', E'[\\\\1](\\\\2)', 'g');

إذًا ما الأمر؟