2

The problem is I don't know the length of the input string. My function can only replace if the input string is "yyyy". I think of the solution is that first, we will try to convert the input string back to "yyyy" and using my function to complete the work.

Here's my function:

void findAndReplaceAll(std::string & data, std::string toSearch, std::string replaceStr)
{
    // Get the first occurrence
    size_t pos = data.find(toSearch);

    // Repeat till end is reached
    while( pos != std::string::npos)
    {
        // Replace this occurrence of Sub String
        data.replace(pos, toSearch.size(), replaceStr);
        // Get the next occurrence from the current position
        pos = data.find(toSearch, pos + replaceStr.size());
    }
}

My main function

std::string format = "yyyyyyyyyydddd";
findAndReplaceAll(format, "yyyy", "%Y");
findAndReplaceAll(format, "dd", "%d");

My expected output should be :

%Y%d
Nguyễn Đức Tâm
  • 1,017
  • 2
  • 10
  • 24
  • 1
    Does this answer your question? [Replace part of a string with another string](https://stackoverflow.com/questions/3418231/replace-part-of-a-string-with-another-string) – Azeem Nov 04 '19 at 05:10
  • I don't think so, because my string has only 1 type of character but does not know its exact length. – Nguyễn Đức Tâm Nov 04 '19 at 06:41
  • The answers in that thread are handling variable sizes as well. Maybe, there's more to your use-case. You need to update your question with a complete working example and the inputs and outputs for your string replacement scenarios. – Azeem Nov 04 '19 at 06:50
  • Sorry for my bad, I have just edited the post. I hope you can help me out. – Nguyễn Đức Tâm Nov 04 '19 at 07:00
  • Check this live run: https://ideone.com/ngZ8Jo. Isn't this correct? The two groups of `toSearch` string have been replaced with the `replaceStr`. – Azeem Nov 04 '19 at 07:10
  • Yes, it is. But my expected output is only `%Y`. – Nguyễn Đức Tâm Nov 04 '19 at 07:16
  • For string `yyyyyyyyyy`, how many replacements? Only one `%Y` for the whole string? – Azeem Nov 04 '19 at 07:19
  • Yes, that's. I have edited my post once more to make sure that you understand what I mean. Sorry, if I wasted your time. – Nguyễn Đức Tâm Nov 04 '19 at 07:26

1 Answers1

5

Use regular expressions.

Example:

#include <iostream>
#include <string>
#include <regex>
int main(){
    std::string text = "yyyyyy";
    std::string sentence = "This is a yyyyyyyyyyyy.";
    std::cout << "Text: " << text << std::endl;
    std::cout << "Sentence: " << sentence << std::endl;

    // Regex
    std::regex y_re("y+"); // this is the regex that matches y yyy or more yyyy

    // replacing
    std::string r1 = std::regex_replace(text, y_re, "%y"); // using lowercase
    std::string r2 = std::regex_replace(sentence, y_re, "%Y"); // using upercase 

    // showing result
    std::cout << "Text replace: " <<   r1 << std::endl;
    std::cout <<  "Sentence replace: " << r2 << std::endl;
    return 0;
}

Output:

Text: yyyyyy
Sentence: This is a yyyyyyyyyyyy.
Text replace: %y
Sentence replace: This is a %Y.

If you want to make it even better you can use:

// Regex
std::regex y_re("[yY]+");

That will match any mix of lowercase and upper case for any amount of 'Y's . Example output with that Regex:

Sentence: This is a yYyyyYYYYyyy.
Sentence replace: This is a %Y.

This is just a simple example of what you can do with regex, I'd recommend to look at the topic on itself, there is plenty of info her in SO and other sites.

Extra: If you want to match before replacing to alternate the replacing you can do something like:

 // Regex
    std::string text = "yyaaaa";
    std::cout << "Text: " << text << std::endl;
    std::regex y_re("y+"); // this is the regex that matches y yyy or more yyyy


    std::string output = "";
    std::smatch ymatches;
    if (std::regex_search(text, ymatches, y_re)) {
        if (ymatches[0].length() == 2 ) {
            output = std::regex_replace(text, y_re, "%y");
        } else {
            output = std::regex_replace(text, y_re, "%Y");
        }
    }
J. García
  • 1,859
  • 1
  • 12
  • 13
  • Thanks, your answer works perfectly. I have another question, what about except `yy` because when it comes to `yy` I will replace it with `%y` not `%Y`. Thanks in advance – Nguyễn Đức Tâm Nov 04 '19 at 07:32
  • Then you would have to do a test to see if your input string matches to yy first. You can do that with `regex_match()` – J. García Nov 04 '19 at 07:49
  • I will add another snippet to the answer. It didn't work here. – J. García Nov 04 '19 at 07:54
  • There is a problem, my input string should be like this `yyaa` so I guess that your `yy_re` can't do the job. I think just a little fix with the regex. I mean exactly two `y` character, but the input string will contain some more characters not just only char `y`. – Nguyễn Đức Tâm Nov 04 '19 at 08:05
  • If you pass `yyaa` as input it will output `%yaa`. I understood that is what you needed. – J. García Nov 04 '19 at 08:07
  • The output is `%Yaa` because when it comes to the `if` it gives a false. – Nguyễn Đức Tâm Nov 04 '19 at 08:10
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/201819/discussion-between-nguyn-dc-tam-and-j-garcia). – Nguyễn Đức Tâm Nov 04 '19 at 08:11
  • So turns out, you would have to use regex_search instead of regex_match for the if check, match function expects exact match, search will check if it contains the regex. – J. García Nov 04 '19 at 08:22
  • Do you think there is a problem with the regex because if you use the search here, turn out that it will never reach the else statement(except only 1 `y`) if the input string contains from 2 `y` or more it will never reach the else statement. – Nguyễn Đức Tâm Nov 04 '19 at 08:27
  • Yes there is one, now that you mention it. It would have to be a bit more specific. you have to check for maybe another non y character after 2 ocurrences I think that is [^y]. But I will check and maybe update this tomorrow morning. – J. García Nov 04 '19 at 08:34
  • 1
    No problem. So I edited the snippet with what I came up with only match two yy use %y and if anything else use %Y. Basically, the easiest way I could come up with is just to check the size of the match and do accordingly. – J. García Nov 04 '19 at 15:23