#include <iostream>
#include <string>

typedef std::string::size_type pos_t;

std::string cleanLinks (const std::string & s)
{
    pos_t openBrackets = s.find("[[");
    // Set the result as anything before the first link.
    std::string result = s.substr(0,openBrackets);
    if ( std::string::npos == openBrackets )
        return result;

    // Search on from the first opening brackts to the closing brackets.
    pos_t closeBrackets = s.find("]]", openBrackets);
    if ( std::string::npos == closeBrackets )
        return result;

    // At this point, result contains anything up to the first link ("[[").
    // If there are no links, we won't get here.

    // Make a string consisting of just the (first) link.
    std::string linkStr = s.substr(openBrackets, closeBrackets-openBrackets+2);

    // If the link contains a |, split it out into text, and add that to
    // the result. Otherwise add the whole thing to the result unchanged.
    pos_t pipePos = linkStr.find("|");
    if ( std::string::npos == pipePos )
    {
        result += linkStr;
    }
    else
    {
        result += linkStr.substr(2, pipePos-2);
    }

    // Clean up any links in the rest of the string, then give it all back.
    return result + cleanLinks(s.substr(closeBrackets+2, std::string::npos));
}

int main()
{
    std::string inp =
        "This is a link [[abcd 1234|xyz 1234]]  "
        "[[India]] [[abcd 1234|xyz 1234]]";
    std::cout << '\"' << inp << "\"\n\"" << cleanLinks(inp) << "\"\n";
    return 0;
}