TGViewer
C# Geeks (.NET) C# Geeks (.NET) @csharpgeeks · 550 subscribers
Post #715 361
🧵 یکی از چالش‌های همیشگی و آزاردهنده برای توسعه‌دهندگان در هنگام پردازش متون، مدیریت کاراکترهای پایان خط یا همان خط جدید (Newline) بوده است.
😓 تفاوت در نحوه ذخیره‌سازی خطوط جدید در سیستم‌عامل‌های مختلف و همچنین استانداردهای گوناگون انکودینگ، همواره باعث بروز باگ‌های پنهان در پردازش متن و عبارات باقاعده (Regex) می‌شود.
🎉 خوشبختانه مایکروسافت در NET 11. با معرفی یک قابلیت جدید و کاربردی به نام RegexOptions.AnyNewLine، این گره کور را باز کرده‌است.
در این مقاله، به بررسی این چالش قدیمی، مشکلات راهکارهای سنتی و نحوه حل اصولی آن در دات‌نت ۱۱ می‌پردازیم.
📌 چالش تاریخی: تنوع استانداردهای خط جدید

از گذشته تا به امروز، سیستم‌عامل‌های مختلف روش‌های متفاوتی برای تعریف پایان یک خط داشته‌اند.
به طور سنتی، سه فرمت اصلی وجود داشت:

🪟 ویندوز (Windows): استفاده از ترکیب \r\n (CRLF)
🐧 یونیکس و لینوکس (Unix & Linux): استفاده از \n (LF)
🍎 مک‌اواس قدیمی (Older MacOS): استفاده از \r (CR)

🌍 با ظهور استاندارد Unicode، این تنوع باز هم فراتر رفت و سه کاراکتر دیگر نیز به این جمع اضافه شدند:
🔹 Next Line (\u0085 - NEL)
🔹 Line Separator (\u2028 - LS)
🔹 Paragraph Separator (\u2029 - PS)

💡 حال تصور کنید متنی ترکیبی دارید که از منابع مختلف (وب‌سرویس‌ها، فایل‌های آپلود شده توسط کاربران با سیستم‌عامل‌های گوناگون و دیتابیس‌ها) جمع‌آوری شده و شامل انواع این کاراکترهاست:
var text = "The Quick\r\nBrown Fox\u0085Jumped Over\u2028The Lazy Dog\nBigly";

🎯 هدف ما این است که خطوط این متن چندخطی (Multiline) را به صورت تفکیک‌شده استخراج کنیم.
🔍 بررسی عملکرد در نسخه‌های قدیمی دات‌نت
در NET 10. و نسخه‌های پیش از آن، برای استخراج خطوط معمولاً از الگوی زیر استفاده می‌شد:
var oldLines = Regex.Matches(text, @"^.*$", RegexOptions.Multiline)
.Select(r => r.Value)
.ToArray();

در این عبارت باقاعده:
📍 علامت ^ نشان‌دهنده ابتدای خط است.
📍 الگوی .* هر کاراکتری به جز \n را به تعداد دلخواه جستجو می‌کند.
📍 علامت $ نشان‌دهنده انتهای خط است.
📍 گزینه RegexOptions.Multiline به موتور پردازش اعلام می‌کند که متن ورودی ساختار چندخطی دارد.
❓ مشکل کجاست؟
⚠️ موتور Regex دات‌نت به طور سنتی فقط کاراکتر \n (LF) را به عنوان جداکننده خط در حالت Multiline می‌شناسد.
در نتیجه اجرای کد بالا روی متن نمونه، خروجی مطلوبی نخواهد داشت:
❌ کاراکترهای یونیکد مانند \u0085 یا \u2028 اصلاً شناسایی نمی‌شوند و خطوط متصل به آن‌ها جدا نخواهند شد.
❌ در مورد ویندوز (\r\n) نیز، از آنجا که فقط \n به عنوان پایان خط در نظر گرفته می‌شود، کاراکتر \r (Carriage Return) به عنوان بخشی از متن خط اول استخراج می‌شود و معمولاً باید با متدهایی مانند Trim() حذف شود.

🚀 راهکار دات‌نت ۱۱: پرچم RegexOptions.AnyNewLine

مایکروسافت در نسخه NET 11.، پرچم جدیدی به نام RegexOptions.AnyNewLine به کلاس Regex اضافه کرده است.
✨ با فعال‌سازی این گزینه، لنگرهای سر خط (^)، ته خط ($)، پایان رشته (\Z) و همچنین کاراکتر نقطه (.)، به صورت هوشمند تمامی استانداردهای خط جدید (اعم از ویندوز، لینوکس و انواع یونیکدها) را به رسمیت می‌شناسند.
کد بهینه‌شده در NET 11. به شکل زیر تغییر می‌کند:
var text = "The Quick\r\nBrown Fox\u0085Jumped Over\u2028The Lazy Dog\nBigly";

// استفاده همزمان از حالت چندخطی و پرچم جدید AnyNewLine
var newLines = Regex.Matches(
text,
@"^.*$",
RegexOptions.Multiline | RegexOptions.AnyNewLine)
.Select(r => r.Value)
.ToArray();

foreach (var line in newLines)
{
Console.WriteLine($"Line: {line}");
}

✅ چرا این راهکار بسیار کارآمدتر است؟
🌍 1. شناسایی کامل Unicode

تمام کاراکترهای پایان خط یونیکد، بدون نیاز به نوشتن Patternهای پیچیده و طولانی، به طور خودکار پردازش می‌شوند.
⚡️ 2. یکپارچه‌سازی اتمیک \r\n

برخلاف ترفندهای قدیمی (مانند استفاده از \r?$) که کاراکتر \r را به عنوان بخشی از تطابق (Match) برمی‌گرداندند،
گزینه AnyNewLine با ترکیب \r\n به عنوان یک موجودیت واحد (Atomic) برخورد می‌کند و از ورود کاراکتر مزاحم \r به خروجی نهایی جلوگیری می‌کند.
🎯 جمع‌بندی
✨ معرفی قابلیت RegexOptions.AnyNewLine در NET. 11 گام مهمی در جهت بهبود پایداری و سادگی پردازش متون چندزبانه و بین‌المللی است.
✅ با به‌کارگیری این پرچم، دیگر نیازی به نوشتن متدهای کمکیِ سنگین برای نرمال‌سازی خطوط پیش از اعمال Regex یا استفاده از Patternهای پیچیده و غیراستاندارد نخواهید داشت.
More from @csharpgeeks
  1. Sep 22, 2026یه مدتی قراره از دنیای NET. فاصله بگیرم، چون وقتشه برم سربازی. راستش نمیدونم این مدت رو چج…
  2. Sep 20, 2026🔥 حالا مشکل اصلی: Alert Storm فرض کن Database از دسترس خارج شده. ۱۰۰ Pod داری. هر Pod می‌…
  3. Sep 20, 2026🚨 طراحی سیستم Monitoring و Alerting در یک سیستم بزرگ فرض کن ساعت ۳ صبح است. سیستم شما با…
  4. Sep 19, 2026#Engineering_Leadership تصمیم نگرفتن هم یک تصمیم است یه چیز عجیب توی تیم‌های مهندسی: گاهی…
  5. Sep 19, 2026☑ چک‌لیست آماده‌سازی تیم، فرایندها و زیرساخت برای توسعه با AI توجه: هیچ چک‌لیستی جهان‌شمول…
  6. Sep 19, 2026📌پایان یک انتظار طولانی: اعتبارسنجی ناهمگام (Async Validation) در NET 11.
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →