簡體   English   中英

替換字符串中空格的策略

[英]Strategy to replace spaces in string

我需要存儲一個用某些字符替換其空格的字符串。 當我找回它時,我需要再次用空格替換字符。 我已經考慮過這種策略,在存儲時我將替換(用_a表示空格)和(_a用_aa表示),而檢索時將替換(用空格的_a表示)和(用_a的_aa表示)。 即,即使用戶在字符串中輸入_a也會被處理。 但是我不認為這是一個好策略。 請讓我知道是否有人有更好的選擇?

東西更換空間是一個問題,當事情已經是的字符串中。 為什么不簡單地對字符串進行編碼-有很多方法可以做到這一點,一種方法是將所有字符都轉換為十六進制。

例如

  Hello world!

編碼為

  48656c6c6f20776f726c6421

空格為0x20。 然后,您只需將字符串解碼回(十六進制為ascii)即可。
這樣,編碼字符串中就沒有空格。

- 編輯 -優化-

您可以用%xx替換字符串中的所有%和所有空格,其中xx是字符的十六進制代碼。

例如

   Wine having 12% alcohol

變成

   Wine%20having%2012%25%20alcohol
  • %20是空格
  • %25是%字符

這樣, % (空格)不再是問題-解碼很容易。

編碼算法

   - replace all `%` with `%25`
   - replace all ` ` with `%20`

解碼算法

   - replace all `%xx` with the character having `xx` as hex code

(你甚至可以優化更多,因為你需要編碼只有兩個字:使用%1%%2 ,但我建議您使用%xx解決方案,因為它具有更高的可移植性-如果以后需要編碼更多字符,可以稍后使用)

我不確定您的解決方案是否有效。 在閱讀時,如何區分最初為" a"字符串和最初為"_a"字符串:如果我理解正確,則兩者都將以"_aa"結尾。

通常,在某種情況下,特定的字符集不能這樣顯示,而必須進行編碼,解決方案是選擇一個允許的字符作為“轉義”字符,將其從允許的字符集中刪除,並對所有字符進行編碼禁止字符(包括轉義字符)中的兩個字符序列(以轉義字符開頭)。 例如,在C ++中,字符串或字符文字中不允許換行。 轉義字符為\\ ; 因此,還必須將其編碼為轉義序列。 因此,對於新行,我們有"\\n"n的選擇是任意的),對於\\"\\\\" (對於第二個字符, \\的選擇也是任意的,但是使用轉義的轉義字符表示自己是很平常的。)在這種情況下,如果要使用_作為轉義字符,請使用"_a"代表一個空格,邏輯上的選擇是代表一個_ "__" (但我建議在視覺上更具啟發性-可能是^作為轉義符,其中"^_"代表一個空格, "^^"代表a ^ )。 閱讀時,無論何時看到轉義字符,都必須映射以下字符(如果不是預定義的映射之一,則輸入文本有誤)。 這很容易實現,而且非常可靠; 唯一的缺點是,在極端情況下,它會使字符串的大小加倍。

您想使用C / C ++來實現嗎? 我認為您應該將字符串分成多個部分,並以空格分隔。

如果您的字符串是這樣的:“ a__b”(連續多個空間),它將被拆分為:

sub[0] = "a";
sub[1] = "";
sub[2] = "b";

希望這會有所幫助!

對於使用X個字符的普通字符串,您不能僅使用1個字符/輸入字符使用x-1編寫或編碼字符串。 您可以使用2個字符的組合來替換給定字符(這正是您在示例中嘗試的字符)。

為此,請遍歷字符串以計算空格的出現及其長度,然后創建一個新的字符數組,並用“ //”替換這些空格,但這只是一個示例。 這種方法的問題在於,輸入字符串中不能包含“ //”。

另一種方法是使用很少使用的字符(例如“ ^”)替換空格。

最后一種方法在這兩種方法的組合中很流行。 在Unix和php中使用它來將語法字符作為字符串中的文字。 如果您想要一個“”,只需將其寫為“ \\”等。

為什么不使用替換功能

String* stringWithoutSpace= stringWithSpace->Replace(S" ", S"replacementCharOrText");

所以現在stringWithoutSpace不包含空格。 當您想把這些空間放回去時,

String* stringWithSpacesBack= stringWithoutSpace ->Replace(S"replacementCharOrText", S" ");

我想這個問題比出現的更多。 例如,您要存儲的字符串不僅必須沒有空格,而且還必須看起來像單詞或類似的東西。 您應該清楚自己的要求(並且可以考慮通過解釋為什么需要這樣做來滿足觀眾的好奇心。)

編輯:正如JamesKanze在評論中指出的那樣,在您可以連續使用多個空間的情況下,以下內容將不起作用。 但是我還是把它留在這里,以供歷史參考。 (我對其進行了修改以壓縮連續的空間,因此至少會產生明確的輸出。)

std::string out;
char prev = 0;
for (char ch : in) {
  if (ch == ' ') {
    if (prev != ' ') out.push_back('_');
  } else {
    if (prev == '_' && ch != '_') out.push_back('_');
    out.push_back(ch);
  }
  prev = ch;
}
if (prev == '_') out.push_back('_');

我認為僅編碼為十六進制的ascii是一個好主意,但是當然會使所需的存儲量增加一倍。

如果要使用較少的內存來執行此操作,則將需要兩個字母的序列,並且必須小心以方便返回。

例如,您可以用_a替換空格,但是您還需要注意轉義符_ 為此,將每個_替換為__ (兩個下划線)。 您需要掃描一次字符串,然后同時進行兩個替換。

這樣,在結果文本中,所有原始下划線都會加倍,並且下划線的唯一出現是在_a組合中。 您可以放心地將其翻譯回來。 每當您看到下划線時,您都需要將數字加注為1,然后再查看。 如果跟隨a ,則之前是空白。 如果_跟在后面,則之前是下划線。

請注意,關鍵是要替換原始字符串中的轉義字符( _ ),而不是將空白映射到的字符序列。 您的想法是替換_a換行符。 因為您不知道_aa最初是_a還是a (空格后跟a)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM