2012-03-29 143 views
49

我有一個包含二進制數字的字符串。如何在每個8位數後分隔字符串?在每N個字符處添加分隔符到字符串?

假設字符串爲:

string x = "111111110000000011111111000000001111111100000000"; 

我希望每個8個字符後添加喜歡,(逗號)分隔。

輸出應該是:

"11111111,00000000,11111111,00000000,11111111,00000000," 

然後我想將它發送到一個列表<>去年8月1日字符,然後前面的8個字符(除)等。

我該怎麼做?

+1

你可以使用char或字節數組。 – 2012-03-29 19:27:55

+4

看到這個:http://stackoverflow.com/questions/3436398/convert-a-binary-string-representation-to-a-byte-array – Ryan 2012-03-29 19:28:22

+0

我可以做的第一件事情與string.Format()?如果不是如何? – 2012-03-29 19:31:25

回答

91
Regex.Replace(myString, ".{8}", "$0,"); 

如果你想八字符串數組,再下面是可能更容易:

Regex.Split(myString, "(?<=^(.{8})+)"); 

將只在點在那裏的8個字符的多個它前面拆分字符串。

+1

+1哇,這是一個非常好的正則表達式學習! – dasblinkenlight 2012-03-29 19:41:01

+1

可能值得聲稱他們只是二進制「數字」,而不是任何字符:''[01] {8}「' – GalacticCowboy 2012-03-29 19:53:37

+3

那麼,我希望他們知道他們扔進這個數據的是什麼樣的數據:) – Joey 2012-03-29 19:55:57

28

試試這個:

var s = "111111110000000011111111000000001111111100000000"; 
var list = Enumerable 
    .Range(0, s.Length/8) 
    .Select(i => s.Substring(i*8, 8)) 
    .ToList(); 
var res = string.Join(",", list); 
+1

這是一個很棒的解決方案。 – 2012-03-29 19:32:57

+0

是的確...謝謝@dasbinkeblight – 2012-03-29 19:36:35

+1

順便說一句,你不需要'ToList()',因爲'string.Join'具有[需要IEnumerable'的重載](http://msdn.microsoft.com/en-us /library/dd992421.aspx)(自.NET 4開始)。 – Joey 2012-03-29 19:57:18

2

如果我正確理解你的最後一個要求(這不是我清楚,如果你需要的中間用逗號分隔的字符串或沒有),你可以這樣做:

var enumerable = "111111110000000011111111000000001111111100000000".Batch(8).Reverse(); 

利用morelinq。使用LINQ

+0

如果只有'Batch'是標準的:(在任何情況下,這是知道更多的LINK的手 – 2012-03-29 19:40:21

1

方式一:

string data = "111111110000000011111111000000001111111100000000"; 
const int separateOnLength = 8; 

string separated = new string(
    data.Select((x,i) => i > 0 && i % separateOnLength == 0 ? new [] { ',', x } : new [] { x }) 
     .SelectMany(x => x) 
     .ToArray() 
    ); 
+0

此代碼插入從右到左的分隔符。而不是從左到右 – 2016-03-27 21:22:31

2

還有一個正則表達式的方法:

var str = "111111110000000011111111000000001111111100000000"; 
# for .NET 4 
var res = String.Join(",",Regex.Matches(str, @"\d{8}").Cast<Match>()); 

# for .NET 3.5 
var res = String.Join(",", Regex.Matches(str, @"\d{8}") 
      .OfType<Match>() 
      .Select(m => m.Value).ToArray()); 
+0

我喜歡這種方法作爲「件是可以理解的」,甚至如果它在.NET 3.5中需要更多一點fudge – 2012-03-29 19:48:40

+0

感謝您的補充:) - 我一直忘記檢查框架兼容性。 – Alex 2012-03-29 19:50:07

+0

此代碼刪除characters.Separators將替換爲字符串和字符串將丟失。 – 2016-03-27 21:18:12

1

...或老同學:

public static List<string> splitter(string in, out string csv) 
{ 
    if (in.length % 8 != 0) throw new ArgumentException("in"); 
    var lst = new List<string>(in/8); 

    for (int i=0; i < in.length/8; i++) lst.Add(in.Substring(i*8,8)); 

    csv = string.Join(",", lst); //This we want in input order (I believe) 
    lst.Reverse(); //As we want list in reverse order (I believe) 

    return lst; 
} 
+0

我稱之爲「Java」。不,謝謝:-) – 2012-03-29 19:48:04

+0

我稱之爲易讀 - 但對每個人都是這樣:D除了這裏的正則表達式方法外,Linq方法在幕後正在做的事情是循環切入 - 更簡單讀書。我喜歡上面的批處理方法,對我來說這是一個新的方法:) – Wolf5370 2012-03-29 19:53:22

+0

雖然'length'不是'System.String'的成員,它甚至不會編譯。 – Joey 2014-03-14 08:16:17

2

醜陋但不太垃圾:

private string InsertStrings(string s, int insertEvery, char insert) 
{ 
    char[] ins = s.ToCharArray(); 
    int length = s.Length + (s.Length/insertEvery); 
    if (ins.Length % insertEvery == 0) 
    { 
     length--; 
    } 
    var outs = new char[length]; 
    long di = 0; 
    long si = 0; 
    while (si < s.Length - insertEvery) 
    { 
     Array.Copy(ins, si, outs, di, insertEvery); 
     si += insertEvery; 
     di += insertEvery; 
     outs[di] = insert; 
     di ++; 
    } 
    Array.Copy(ins, si, outs, di, ins.Length - si); 
    return new string(outs); 
} 

字符串超載:

private string InsertStrings(string s, int insertEvery, string insert) 
{ 
    char[] ins = s.ToCharArray(); 
    char[] inserts = insert.ToCharArray(); 
    int insertLength = inserts.Length; 
    int length = s.Length + (s.Length/insertEvery) * insert.Length; 
    if (ins.Length % insertEvery == 0) 
    { 
     length -= insert.Length; 
    } 
    var outs = new char[length]; 
    long di = 0; 
    long si = 0; 
    while (si < s.Length - insertEvery) 
    { 
     Array.Copy(ins, si, outs, di, insertEvery); 
     si += insertEvery; 
     di += insertEvery; 
     Array.Copy(inserts, 0, outs, di, insertLength); 
     di += insertLength; 
    } 
    Array.Copy(ins, si, outs, di, ins.Length - si); 
    return new string(outs); 
} 
0

這是更快而不復制陣列(這個版本的插入空間,每3個數字,但你可根據您的需要調整)

public string GetString(double valueField) 
{ 
    char[] ins = valueField.ToString().ToCharArray(); 
    int length = ins.Length + (ins.Length/3); 
    if (ins.Length % 3 == 0) 
    { 
     length--; 
    } 
    char[] outs = new char[length]; 

    int i = length - 1; 
    int j = ins.Length - 1; 
    int k = 0; 
    do 
    { 
     if (k == 3) 
     { 
      outs[i--] = ' '; 
      k = 0; 
     } 
     else 
     { 
      outs[i--] = ins[j--]; 
      k++; 
     }   
    } 
    while (i >= 0); 

    return new string(outs); 
} 
+0

我不明白這一點。 valueField一個double?你將輸入字符串轉換爲double,以便在函數中使用它,然後將其重新轉換爲字符串和charArray?你介意對代碼進行一些評論嗎? – Joze 2015-05-21 09:04:04

+0

我沒有輸入字符串。我只有一個double值,這就是爲什麼'valueFiled'是double的原因。如果你有字符串值,那麼你可以創建'valueFiled'字符串並將第一行改爲'char [] ins = valueField.ToCharArray();'。 – 2015-05-27 13:45:23

0

有點遲到了,但這裏有一個簡單的LINQ表達式打破輸入字符串x成另一個字符串sep分離的n組:

string sep = ","; 
int n = 8; 
string result = String.Join(sep, x.InSetsOf(n).Select(g => new String(g.ToArray()))); 

的快速綱要發生了什麼這裏:

  • x被視爲IEnumberable<char>,這是其中InSetsOf擴展方法進來
  • InSetsOf(n)組字符到的IEnumerable一個IEnumerable - 在外部分組中的每個條目包含的字符n的內基。
  • Select方法中,通過使用String()構造函數將n字符的每個組轉換回字符串,該構造函數採用chars的數組。
  • Select的結果現在是IEnumerable<string>,它被傳遞到String.Join以交織sep字符串,就像任何其他示例一樣。
-1

我比後期多與我的答案,但你可以用這一個:

static string PutLineBreak(string str, int split) 
    { 
     for (int a = 1; a <= str.Length; a++) 
     { 
      if (a % split == 0) 
       str = str.Insert(a, "\n"); 
     } 

     return str; 
    }