2014-10-21 5 views
1

У меня длинная последовательность сегментов, разделенных разделителем say '-'. Он имеет форму:Проверка строки для подстановки подстрок

I-am-logged-into-StackOverFlow-I-am-using-StackOverFlow- 
I-am-reading-a-book-A-I-have-written-a-book-B- 

Пользователь указывает сегменты, которые мне нужно сравнить.

Скажем, для строки - 1, выше: он вводит 5 и 9. Оба содержат StackOverflow, поэтому я возвращаюсь истинную.

Для струн - 2, сегментов 6, 12. Но. они разные книги A, B. Итак, я возвращаю false.

Я попытался сделать это, используя std :: regex.

Для всех индексов не введенных пользователем, заливаю в тех частях временной последовательности с
([^ -] +) -, т.е. строка из одного или нескольких символов, не содержащих - , но заканчивая этим.

Для двух индексов пользовательские входы, я сталкиваюсь с проблемой. Если я пойду с группами захвата и укажите ([^ -] + -) в первом индексе и используйте \ 1 (или любую n-ю группу захвата) для второго индекса, результаты несовместимы. Книга соответствует Номерной фонд, который не является ожидаемым. В некоторых случаях a- соответствует с not-.

Затем я сопоставляю предложения, приведенные выше, с этой временной строкой.

Как проверить равенство - символы от начала до конца и длину подстрок по заданным индексам?

Кроме того, я нахожу этот вопрос похожим, но некоторые из результатов там несовместимы. Constructing a regular expression

PS: Учитывая тот факт, что легко выполнять регулярное выражение, а не извлекать сегменты по заданным индексам строки и сравнивать их, я бы предпочел первый. Количество строк может превышать сотни.

Улучшенные решения оценены.

ответ

1

Возможное решение (конечно, не только один) может быть просто использовать std::find и извлечь две подстроки для сравнения

(предупреждение: следующий код не был тщательно протестирован и может содержать ошибки, то задумана как идея концепции для дальнейшей доработки в соответствии с вашими потребностями)

bool match_positions(const std::string& str, int p1, int p2) { 
    int wordNo = 1; 
    size_t beg = 0, pos; 
    std::string first, second; 
    while ((pos = str.find('-', beg)) != std::string::npos || 
     (first.empty() && second.empty())) { 
     if (wordNo == p1) 
      first = str.substr(beg, pos - beg); 
     if (wordNo == p2) 
      second = str.substr(beg, pos - beg); 
     beg = pos + 1; 
     ++wordNo; 
    } 
    if (first.empty() || second.empty()) 
     return false; 
    else 
     if (!first.compare(second)) 
      return true; 
     else 
      return false; 
} 

Example

Так как это (как я понял), проблема «find-the-substring-at-nth-delimiter», я бы не пошел на регулярное выражение и не оставил их для более сложных задач сопоставления шаблонов.

+0

Я сожалею. Это то, что я имею в виду, извлекая сегменты. То есть ** найдите ** необходимые «-» позиции и извлеките подстроку. Тогда сравните то же самое. –

+0

@KutKV взгляните на пример, который я опубликовал, это то, что вы хотите? Правильно ли я понял? –

+0

Хорошо, я буду помнить об этом. Я планирую построить временную строку, как сказано выше, использовать это как регулярное выражение, а затем выполнить regex_match в списке строк, которые у меня есть. –

0

Я согласен с Марко А. Регулярные выражения излишние для этой работы. Работающий вариант с istringstream:

#include<iostream> 
#include<string> 
#include<sstream> 
#include<limits> 

bool equalSubStr(const std::string& str, int i1, int i2, char sep) { 
    std::istringstream ss(str); 
    std::string sub1, sub2; 
    int i=1; 
    if(i1 > i2) 
     std::swap(i1,i2); 

    auto advance = [&ss,sep](int &i, int iLim) { 
     for(; i!=iLim; i++) { 
      if(!ss.ignore(std::numeric_limits<std::streamsize>::max(),sep)) 
       return false; 
     } 
     return true; 
    }; 

    if((advance(i,i1) 
      && std::getline(ss,sub1,sep) 
      && advance(++i,i2) 
      && std::getline(ss,sub2,sep))) 
     return sub1 == sub2; 

    return false; 
} 

int main() 
{ 
    std::string str1="I-am-logged-into-StackOverFlow-I-am-using-StackOverFlow-"; 

    int i1=5; 
    int i2=9; 

    if(equalSubStr(str1,5,9,'-')) 
     std::cout << "\nSubstrings 5 and 9 are equal."; 
    if(equalSubStr(str1,1,6,'-')) 
     std::cout << "\nSubstrings 1 and 6 are equal."; 
    if(!equalSubStr(str1,2,3,'-')) 
     std::cout << "\nSubstrings 2 and 3 are not equal."; 

    return 0; 
} 

/* 
    Local Variables: 
    compile-command: "g++ --std=c++11 test.cc -o ./test.exe && ./test.exe" 
    End: 
*/ 
+0

Спасибо. ** istringstream ** - это то, что я новичок для меня. –