2016-08-03 4 views
0

Я создал это регулярное выражение и использовал значение для печати в строку.Regex-ed значение String

std::string s (filename); 
    std::smatch m; 
    std::regex e ("\/(?:.(?!\/))+$"); 

    while (std::regex_search (s,m,e)) { 
    for (auto p:m) std::cout << p << " "; 

    s = m.suffix().str(); 
    } 
    std::string currFileName = s; 

    std::string Original = filename; 
    std::string newFile = Original + currFileName; 
    std::cout << newFile; 

Проблема не в терминале.

печатное

/simple-loops.cc /home/fypj/build/simple-loops.cc 

Ожидаемое значение

/home/fypj/build/simple-loops.cc/simple-loops.cc 

Вы можете спросить, что имя файла является

llvm::StringRef filename; 
SourceLocation ST = f->getSourceRange().getBegin(); 
filename = Rewrite.getSourceMgr().getFilename(ST); 
+0

Да, как выглядит строка * filename? Является ли напечатанное значение таким же, как и входящим? –

+0

@wiktorstribizew /home/fypj/build/simple-loops.cc/ – HiWorld

+0

Означает ли это, что вы хотите усечь строку в последнем '/'? –

ответ

1

ПРИМЕЧАНИЕ: Возможно, лучший способ продолжить - использовать способ манипуляции с дорогой, описанный, скажем, в сообщении Getting a directory name from a filename.

Отвечая на Ваш вопрос ...

Вы пытаетесь соответствовать последней части пути и добавить его в конец. Вы используете регулярное выражение, которое не соответствует вашей строке, потому что вы хотите сопоставить один или больше символов после последних /, которые не являются / - но ваш вход заканчивается /. "\/(?:.(?!\/))+$" также содержит \/ неправильных последовательностей побега, вы не должны избегать символов /. Имейте в виду, что этот закаленный жадный токен, подобный конструкции, неэффективен, когда вам нужно «отрицать» только один символ - вам нужно negated character class.

Итак, если вы хотите сделать это с помощью регулярных выражений, используйте шаблон, который учитывает / с и использовать его с regex_replace:

#include <iostream> 
#include <regex> 
using namespace std; 

int main() { 
    std::regex reg("/?([^/]+)/?$"); 
    std::string s("/home/fypj/build/simple-loops.cc/"); 
    std::cout << std::regex_replace(s, reg, "/$1/$1/") << std::endl; 
    return 0; 
} 

См детализирует C++ demo

Pattern:

  • /? - опционально /
  • ([^/]+) - Группа 1 (можно ссылаться с $1 от замены скороговорки) захват одного или более символов других, чем / ([^...] является инвертированным символьным классом)
  • $ - конец строки
+0

Прямо сейчас, я использую (http: //www.regexr.com), чтобы получить выражение, но кажется, что этот сайт не очень хорош – HiWorld

+1

'std :: regex' Реализация ECMAScript отличается от JS, поэтому regexr не так хорош для тестирования шаблонов std :: regex C++. Однако простые будут делать. Обратите внимание, что мое демо выше [производит '/home/fypj/build/simple-loops.cc/simple-loops.cc/'](https://ideone.com/Cs5NLY) результат, если ваш вход ['/home /fypj/build/simple-loops.cc/"'](http://stackoverflow.com/questions/38736133/regex-ed-value-to-string/38736663?noredirect=1#comment64847593_38736133). Пожалуйста, будьте более конкретными в отношении ввода. –

+0

@HiWorld: Если вы не смогли использовать этот подход из-за [этой проблемы] (http://stackoverflow.com/questions/38762492/regex-unable-to-print/38762657#38762657), пожалуйста, рассмотрите возможность повторного рассмотрения моего предложения. –