単語を壊さずにc#で長い文字列を壊したい
例:S AAA BBBBBBB CC DDDDDD V
7カウントで文字を壊す:
S AAA
BBBBBBB
CC
DDDDDD
V
どうすればよいですか?
単語を壊さずにc#で長い文字列を壊したい
例:S AAA BBBBBBB CC DDDDDD V
7カウントで文字を壊す:
S AAA
BBBBBBB
CC
DDDDDD
V
どうすればよいですか?
string inputStr = "S AAA BBBBBBB CC DDDDDD V ";
int maxWordLength = 7;
char separator = ' ';
string[] splitted = inputStr.Split(new[]{separator}, StringSplitOptions.RemoveEmptyEntries);
var joined = new Stack<string>();
joined.Push(splitted[0]);
foreach (var str in splitted.Skip(1))
{
var strFromStack = joined.Pop();
var joindedStr = strFromStack + separator + str;
if(joindedStr.Length > maxWordLength)
{
joined.Push(strFromStack);
joined.Push(str);
}
else
{
joined.Push(joindedStr);
}
}
var result = joined.Reverse().ToArray();
Console.WriteLine ("number of words: {0}", result.Length);
Console.WriteLine( string.Join(Environment.NewLine, result) );
プリント:
number of words: 5
S AAA
BBBBBBB
CC
DDDDDD
V
これは、正規表現の力を利用したより短いソリューションです。
string input = "S AAA BBBBBBB CC DDDDDD V";
// Match up to 7 characters with optional trailing whitespace, but only on word boundaries
string pattern = @"\b.{1,7}\s*\b";
var matches = Regex.Matches(input, pattern);
foreach (var match in matches)
{
Debug.WriteLine(match.ToString());
}
私があなたの質問を正しく理解していれば、これはトリックを行います。再帰的な実装はもっとクールだったでしょうが、C#では末尾再帰はあまりにもひどいです:)
また、yieldとを使用して実装することもできますIEnumerable<string>
。
string[] splitSpecial(string words, int lenght)
{
// The new result, will be turned into string[]
var newSplit = new List<string>();
// Split on normal chars, ie newline, space etc
var splitted = words.Split();
// Start out with null
string word = null;
for (int i = 0; i < splitted.Length; i++)
{
// If first word, add
if (word == null)
{
word = splitted[i];
}
// If too long, add
else if (splitted[i].Length + 1 + word.Length > lenght)
{
newSplit.Add(word);
word = splitted[i];
}
// Else, concatenate and go again
else
{
word += " " + splitted[i];
}
}
// Flush what we have left, ie the last word
newSplit.Add(word);
// Convert into string[] (a requirement?)
return newSplit.ToArray();
}
正規表現を試してみませんか?
(?:^|\s)(?:(.{1,7}|\S{7,}))(?=\s|$)
すべてのキャプチャを使用します。
C#コード:
var text = "S AAA BBBBBBB CC DDDDDD V";
var matches = new Regex(@"(?:^|\s)(?:(.{1,7}|\S{7,}))(?=\s|$)").Matches(text).Cast<Match>().Select(x => x.Groups[1].Value).ToArray();
foreach (var match in matches)
{
Console.WriteLine(match);
}
出力:
S AAA
BBBBBBB
CC
DDDDDD
V
string str = "S AAA BBBBBBB CC DDDDDD V";
var words = str.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
StringBuilder sb = new StringBuilder();
List<string> result = new List<string>();
for (int i = 0; i < words.Length; ++i)
{
if (sb.Length == 0)
{
sb.Append(words[i]);
}
else if (sb.Length + words[i].Length < 7)
{
sb.Append(' ');
sb.Append(words[i]);
}
else
{
result.Add(sb.ToString());
sb.Clear();
sb.Append(words[i]);
}
}
if (sb.Length > 0)
{
result.Add(sb.ToString());
}
結果には次のものが含まれます。
S AAA
BBBBBBB
CC
DDDDDD
V
述語は、単語間の区切り文字を7文字に含めるかどうかに応じて調整できます。
HTMLテキストに行区切りを追加する方法は次のとおりです。
SplitLongText(string _SourceText、int _MaxRowLength){
if (_SourceText.Length < _MaxRowLength)
{
return _SourceText;
}
else
{
string _RowBreakText="";
int _CurrentPlace = 0;
while (_CurrentPlace < _SourceText.Length)
{
if (_SourceText.Length - _CurrentPlace < _MaxRowLength)
{
_RowBreakText += _SourceText.Substring(_CurrentPlace);
_CurrentPlace = _SourceText.Length;
}
else
{
string _PartString = _SourceText.Substring(_CurrentPlace, _MaxRowLength);
int _LastSpace = _PartString.LastIndexOf(" ");
if (_LastSpace > 0)
{
_RowBreakText += _PartString.Substring(0, _LastSpace) + "<br/>" + _PartString.Substring(_LastSpace, (_PartString.Length - _LastSpace));
}
else
{
_RowBreakText += _PartString + "<br/>";
}
_CurrentPlace += _MaxRowLength;
}
}
return _RowBreakText;
}
2021年
この拡張方法を見てください、それは再帰性を使用します
public static string SubstringDontBreakWords(this string str, int maxLength)
{
return str.Length <= maxLength ? str : str.Substring(0, str.LastIndexOf(" ")).Trim().SubstringDontBreakWords(maxLength);
}
このように使用してください
string text = "Hello friends";
text.SubstringDontBreakWords(10)