আপনি মাল্টি-লাইন স্ট্রিংগুলিকে লাইনে ভাগ করবেন কীভাবে?
আমি এইভাবে জানি
var result = input.Split("\n\r".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
কিছুটা কুরুচিপূর্ণ দেখায় এবং খালি লাইন হারিয়ে যায়। এর চেয়ে ভাল সমাধান কি আছে?
আপনি মাল্টি-লাইন স্ট্রিংগুলিকে লাইনে ভাগ করবেন কীভাবে?
আমি এইভাবে জানি
var result = input.Split("\n\r".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
কিছুটা কুরুচিপূর্ণ দেখায় এবং খালি লাইন হারিয়ে যায়। এর চেয়ে ভাল সমাধান কি আছে?
উত্তর:
যদি এটি কুৎসিত দেখাচ্ছে, কেবল অপ্রয়োজনীয় ToCharArray
কলটি সরিয়ে ফেলুন ।
আপনি হয় অনুসারে বিভক্ত করতে চান, \n
বা \r
, দুই বিকল্প আছে:
একটি অ্যারে আক্ষরিক ব্যবহার করুন - তবে এটি আপনাকে উইন্ডোজ-স্টাইলের লাইনের শেষের জন্য খালি লাইন দেয় \r\n
:
var result = text.Split(new [] { '\r', '\n' });
বার্ট দ্বারা নির্দেশিত হিসাবে একটি নিয়মিত অভিব্যক্তি ব্যবহার করুন:
var result = Regex.Split(text, "\r\n|\r|\n");
আপনি যদি খালি লাইনগুলি সংরক্ষণ করতে চান, তবে আপনি কেন সি # কে এটিকে ফেলে দেওয়ার জন্য স্পষ্টভাবে বলছেন? ( StringSplitOptions
পরামিতি) - StringSplitOptions.None
পরিবর্তে ব্যবহার করুন।
Environment.NewLine
যতটা আমি উদ্বিগ্ন হ'ল না। প্রকৃতপক্ষে, সমস্ত সম্ভাব্য সমাধানগুলির মধ্যে আমি নিয়মিত এক্সপ্রেশন ব্যবহার করে এমনটিকে পছন্দ করি যেহেতু কেবলমাত্র সমস্ত উত্স প্ল্যাটফর্ম সঠিকভাবে পরিচালনা করে।
StringSplitOptions.RemoveEmptyEntries
।
using (StringReader sr = new StringReader(text)) {
string line;
while ((line = sr.ReadLine()) != null) {
// do something
}
}
string.Split
বা এর সাথে Regex.Split
)?
এটি দুর্দান্ত কাজ করে এবং রেগেক্সের চেয়ে দ্রুত:
input.Split(new[] {"\r\n", "\r", "\n"}, StringSplitOptions.None)
"\r\n"
অ্যারেতে প্রথমে থাকা জরুরী যাতে এটি এক লাইনের বিরতি হিসাবে নেওয়া হয়। উপরেরগুলি এই রেজেক্স সমাধানগুলির উভয়ের মতোই ফলাফল দেয়:
Regex.Split(input, "\r\n|\r|\n")
Regex.Split(input, "\r?\n|\r")
রেজেক্স বাদে প্রায় 10 গুণ কম গতিতে পরিণত হয়। আমার পরীক্ষাটি এখানে:
Action<Action> measure = (Action func) => {
var start = DateTime.Now;
for (int i = 0; i < 100000; i++) {
func();
}
var duration = DateTime.Now - start;
Console.WriteLine(duration);
};
var input = "";
for (int i = 0; i < 100; i++)
{
input += "1 \r2\r\n3\n4\n\r5 \r\n\r\n 6\r7\r 8\r\n";
}
measure(() =>
input.Split(new[] {"\r\n", "\r", "\n"}, StringSplitOptions.None)
);
measure(() =>
Regex.Split(input, "\r\n|\r|\n")
);
measure(() =>
Regex.Split(input, "\r?\n|\r")
);
আউটপুট:
00: 00: 03,8527616
00: 00: 31,8017726
00: 00: 32,5557128
এবং এখানে এক্সটেনশন পদ্ধতি:
public static class StringExtensionMethods
{
public static IEnumerable<string> GetLines(this string str, bool removeEmptyLines = false)
{
return str.Split(new[] { "\r\n", "\r", "\n" },
removeEmptyLines ? StringSplitOptions.RemoveEmptyEntries : StringSplitOptions.None);
}
}
ব্যবহার:
input.GetLines() // keeps empty lines
input.GetLines(true) // removes empty lines
[\r\n]{1,2}
\n\r
বা \n\n
একক লাইন-ব্রেক হিসাবে যা সঠিক নয়।
Hello\n\nworld\n\n
প্রান্তের কেস? এটি পাঠ্যের সাথে স্পষ্টভাবে একটি লাইন, তার পরে একটি খালি রেখা, তারপরে পাঠ্য সহ অন্য একটি লাইন, খালি রেখা পরে।
আপনি Regex.Split ব্যবহার করতে পারেন:
string[] tokens = Regex.Split(input, @"\r?\n|\r");
সম্পাদনা: |\r
(পুরানো) ম্যাক লাইন টার্মিনেটরগুলির অ্যাকাউন্টে যুক্ত করা হয়েছে ।
\r
লাইন শেষ হিসাবে ব্যবহৃত হয় ।
আপনি যদি খালি লাইন রাখতে চান তবে কেবল স্ট্রিংস্প্লিটঅ্যাপশনগুলি সরান।
var result = input.Split(System.Environment.NewLine.ToCharArray());
আমি এই ছিল অন্যান্য উত্তর কিন্তু এই এক, জ্যাক এর উপর ভিত্তি করে উত্তর , উল্লেখযোগ্যভাবে দ্রুততর পছন্দের করা যেতে পারে যেহেতু এটি দ্বারা অ্যাসিঙ্ক্রোনাস কাজ করে, যদিও কিছুটা মন্থর।
public static class StringExtensionMethods
{
public static IEnumerable<string> GetLines(this string str, bool removeEmptyLines = false)
{
using (var sr = new StringReader(str))
{
string line;
while ((line = sr.ReadLine()) != null)
{
if (removeEmptyLines && String.IsNullOrWhiteSpace(line))
{
continue;
}
yield return line;
}
}
}
}
ব্যবহার:
input.GetLines() // keeps empty lines
input.GetLines(true) // removes empty lines
টেস্ট:
Action<Action> measure = (Action func) =>
{
var start = DateTime.Now;
for (int i = 0; i < 100000; i++)
{
func();
}
var duration = DateTime.Now - start;
Console.WriteLine(duration);
};
var input = "";
for (int i = 0; i < 100; i++)
{
input += "1 \r2\r\n3\n4\n\r5 \r\n\r\n 6\r7\r 8\r\n";
}
measure(() =>
input.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None)
);
measure(() =>
input.GetLines()
);
measure(() =>
input.GetLines().ToList()
);
আউটপুট:
00: 00: 03,9603894
00: 00: 00,0029996
00: 00: 04,8221971
কিছুটা বাঁকানো, তবে এটি করার জন্য একটি পুনরুদ্ধারকারী অবরুদ্ধ:
public static IEnumerable<string> Lines(this string Text)
{
int cIndex = 0;
int nIndex;
while ((nIndex = Text.IndexOf(Environment.NewLine, cIndex + 1)) != -1)
{
int sIndex = (cIndex == 0 ? 0 : cIndex + 1);
yield return Text.Substring(sIndex, nIndex - sIndex);
cIndex = nIndex;
}
yield return Text.Substring(cIndex + 1);
}
তারপরে আপনি কল করতে পারেন:
var result = input.Lines().ToArray();
private string[] GetLines(string text)
{
List<string> lines = new List<string>();
using (MemoryStream ms = new MemoryStream())
{
StreamWriter sw = new StreamWriter(ms);
sw.Write(text);
sw.Flush();
ms.Position = 0;
string line;
using (StreamReader sr = new StreamReader(ms))
{
while ((line = sr.ReadLine()) != null)
{
lines.Add(line);
}
}
sw.Close();
}
return lines.ToArray();
}
মিশ্র লাইনের সমাপ্তিগুলি সঠিকভাবে পরিচালনা করা কঠিন । আমরা জানি, লাইন পরিসমাপ্তি অক্ষরের হতে পারেন "লাইন ফিড" (হওয়া ASCII 10, \n
, \x0A
, \u000A
), "গাড়ি ফেরত" (হওয়া ASCII 13, \r
, \x0D
, \u000D
), অথবা তাদের কিছু সংমিশ্রণ। ডস-এ ফিরে গিয়ে উইন্ডোজ দ্বি-চরিত্রের ক্রম সিআর-এলএফ ব্যবহার করে \u000D\u000A
, সুতরাং এই সংমিশ্রণটি কেবল একটি একক লাইন নির্গত করতে হবে। ইউনিক্স একটি একক ব্যবহার করে \u000A
এবং খুব পুরানো ম্যাকগুলি একটি একক \u000D
অক্ষর ব্যবহার করে । একটি একক পাঠ্য ফাইলের মধ্যে এই অক্ষরগুলির স্বেচ্ছাসেবী মিশ্রণের চিকিত্সার মানক উপায়টি নিম্নরূপ:
\u000D\u000A
) অনুসরণ করে তবে এই দুটি একসাথে কেবল একটি লাইন ছেড়ে যায়।String.Empty
একমাত্র ইনপুট যা কোনও লাইন দেয় না (কোনও অক্ষর কমপক্ষে একটি লাইন অন্তর্ভুক্ত করে)পূর্ববর্তী নিয়মটি স্ট্রিংরেডার সম্পর্কিত আচরণ বর্ণনা করে e রিডলাইন এবং সম্পর্কিত ফাংশন, এবং নীচে প্রদর্শিত ফাংশনটি অভিন্ন ফলাফল প্রকাশ করে। এটি একটি দক্ষ সি # লাইন ব্রেকিং ফাংশন যা সিআর / এলএফের যেকোন স্বেচ্ছাসেবী ক্রম বা সংমিশ্রণটি সঠিকভাবে পরিচালনা করতে এই নির্দেশিকাগুলি যথাযথভাবে প্রয়োগ করে। গণিত রেখাগুলিতে কোনও সিআর / এলএফ অক্ষর থাকে না। খালি লাইন সংরক্ষণ করা হয় এবং হিসাবে ফিরে আসে String.Empty
।
/// <summary>
/// Enumerates the text lines from the string.
/// ⁃ Mixed CR-LF scenarios are handled correctly
/// ⁃ String.Empty is returned for each empty line
/// ⁃ No returned string ever contains CR or LF
/// </summary>
public static IEnumerable<String> Lines(this String s)
{
int j = 0, c, i;
char ch;
if ((c = s.Length) > 0)
do
{
for (i = j; (ch = s[j]) != '\r' && ch != '\n' && ++j < c;)
;
yield return s.Substring(i, j - i);
}
while (++j < c && (ch != '\r' || s[j] != '\n' || ++j < c));
}
দ্রষ্টব্য: আপনি যদি StringReader
প্রতিটি কলটিতে একটি উদাহরণ তৈরি করার ওভারহেডটিকে আপত্তি না করেন তবে পরিবর্তে আপনি নীচের সি # 7 কোডটি ব্যবহার করতে পারেন । যেমনটি উল্লেখ করা হয়েছে, উপরে উদাহরণটি আরও কিছুটা দক্ষ হতে পারে তবে এই দুটি ফাংশনই একই ফলাফল দেয় results
public static IEnumerable<String> Lines(this String s)
{
using (var tr = new StringReader(s))
while (tr.ReadLine() is String L)
yield return L;
}