2009-11-30 44 views
8

Cách tốt nhất để thay thế các ký tự trong chuỗi là gì?Ký tự C++ thay thế

Cụ thể:

"This,Is A|Test" ----> "This_Is_A_Test" 

Tôi muốn thay thế tất cả các dấu phẩy, không gian, và "|" với dấu gạch dưới.

(Tôi có quyền truy cập để tăng cường.)

+0

Đây có phải là một chuỗi các lớp std :: string, hoặc một mảng kiểu char với một chấm dứt '\ 0' ? –

+0

nó là một tiêu chuẩn :: string – tinkertime

+6

Tôi nghĩ rằng các câu trả lời replace_if khác nhau, ví dụ: UncleBens, rất tốt. Tuy nhiên, một nhận xét chung: nếu bạn đang thay thế các ký tự để có được thứ gì đó an toàn để sử dụng, ví dụ: dưới dạng tên tệp, bạn nên liệt kê các ký tự được phép và thay thế mọi thứ khác, thay vì theo cách khác. Bằng cách đó bạn sẽ không ngạc nhiên bởi bất kỳ đầu vào lạ nào mà bạn không nghĩ đến. –

Trả lời

9

Khi các câu trả lời khác được chỉ ra, bạn có thể sử dụng các phương thức replace khác nhau. Tuy nhiên, các phương pháp này có nhược điểm là quét chuỗi nhiều lần (một lần cho mỗi ký tự). Tôi muốn giới thiệu phương pháp thay thế của riêng bạn, nếu bạn quan tâm đến tốc độ:

void beautify(std::string &s) { 
    int i; 
    for (i = 0; i < s.length(); ++i) { 
     switch (s[i]) { 
     case ' ': 
     case ',': 
     case '|': 
      s[i] = '_'; 
     } 
    } 
} 
+0

phương pháp thay thế một dòng là tốt đẹp, nhưng giải pháp của bạn hoạt động tốt quá –

+0

Một dòng thay thế chắc chắn là đẹp hơn (tôi nghĩ bạn sẽ cần ít nhất), nhưng nó không hiệu quả. – notnoop

+0

+1 - hợp lệ, hiệu quả, giải pháp lâu hơn :) – Jacob

0

Thư viện chuẩn C++ cũng có quyền truy cập vào các chức năng này mà không cần sử dụng BOOST. Tham khảo replace C++ Reference. Đây có phải là cách tốt nhất ? Tôi đoán đó là để thảo luận. Để thay thế nhiều ký tự khác nhau, bạn có thể phải gọi thay thế nhiều lần.

#include <string> 
    string& replace(size_type index, size_type num, const string& str); 
    string& replace(size_type index1, size_type num1, const string& str, size_type index2, size_type num2); 
    string& replace(size_type index, size_type num, const Char* str); 
    string& replace(size_type index, size_type num1, const Char* str, size_type num2); 
    string& replace(size_type index, size_type num1, size_type num2, Char ch); 

    string& replace(iterator start, iterator end, const string& str); 
    string& replace(iterator start, iterator end, const Char* str); 
    string& replace(iterator start, iterator end, const Char* str, size_type num); 
    string& replace(iterator start, iterator end, size_type num, Char ch); 
    string& replace(iterator start, iterator end, input_iterator start2, input_iterator end2); 

Example program:

// replacing in a string 
#include <iostream> 
#include <string> 
using namespace std; 

int main() 
{ 
    string base="this is a test string."; 
    string str2="n example"; 
    string str3="sample phrase"; 
    string str4="useful."; 

    // function versions used in the same order as described above: 

    // Using positions:    *123456789*12345 
    string str=base;    // "this is a test string." 
    str.replace(9,5,str2);   // "this is an example string." 
    str.replace(19,6,str3,7,6);  // "this is an example phrase." 
    str.replace(8,10,"just all",6); // "this is just a phrase." 
    str.replace(8,6,"a short");  // "this is a short phrase." 
    str.replace(22,1,3,'!');  // "this is a short phrase!!!" 

    // Using iterators:     *123456789* 
    string::iterator it = str.begin(); //^
    str.replace(it,str.end()-3,str3); // "sample phrase!!!" 
    str.replace(it,it+6,"replace it",7); // "replace phrase!!!" 
    it+=8;        //  ^
    str.replace(it,it+6,"is cool");  // "replace is cool!!!" 
    str.replace(it+4,str.end()-4,4,'o'); // "replace is cooool!!!" 
    it+=3;        //   ^
    str.replace(it,str.end(),str4.begin(),str4.end()); 
             // "replace is useful." 
    cout << str << endl; 
    return 0; 
} 
+0

Phương pháp thay thế chỉ thay thế một ký tự (phạm vi), không phải tất cả các lần xuất hiện của một cái gì đó, vì vậy tôi muốn nói nó thực sự không hữu ích cho công việc này :) – UncleBens

+0

Roger. Đó là lý do tại sao tôi nói nó cần phải được chạy nhiều hơn một lần. Cho dù đó là phương pháp tốt nhất, là tùy thuộc vào nhà phát triển –

+0

Thực ra bạn có thể làm cho nước trở nên lầy lội hơn. 'string :: replace' là để thay thế một dải đơn bằng một chuỗi khác (hoặc ký tự). OP chỉ muốn thay thế các ký tự đơn, vì vậy thay vì phương pháp thay thế trọng lượng nặng bạn có thể chỉ vào toán tử [], cho phép bạn "thay thế" giá trị của các ký tự đơn. – UncleBens

3

EDIT: Như Space_C0wb0y nói, replace_if chắc chắn là tốt hơn. Dưới đây là một số mã simpler mẫu:

#include <string> 
#include <iostream> 
#include <algorithm> 
using namespace std; 

bool isBad(char c) 
{ 
const string bad_chars = "|, "; 
return (bad_chars.find(c) != string::npos); 
} 

int main() 
{ 
string str = "This,Is A|Test"; 

// Replace! 
replace_if(str.begin(),str.end(),isBad,'_'); 

cout<<str<<endl; 
return 0; 
} 

OLD ĐÁP:

Sử dụng std::replace với std::find_first_of

11

Bạn có thể sử dụng STL-Algorithm replace_if.

2

tăng :: replace_all (s, cũ, mới);

0

Tôi đã viết thư này, khi Space_C0wb0y đăng câu trả lời của mình, đó là câu trả lời đúng cho câu hỏi của bạn. Điều này phức tạp hơn một chút, nhưng xử lý nhiều sự thay thế có thể có hơn.

(xin lỗi, không được biên dịch/thử nghiệm)

class MyReplacer 
{ 
    friend std::ostream& operator<<(std::ostream& os, const MyReplacer& Repl); 
    public: 
    MyReplacer(char c) : ch(c) {} 
    private: 
    char ch; 
}; 

std::ostream& operator<<(std::ostream& os, const MyReplacer& Repl) 
{ 
    switch (Repl.ch) 
    { 
    case '|': 
    case ' ': 
    case ',': os << '_'; break; 
    default: os << Repl.ch; 
    } 
    return os; 
} 


std::ostringstream oss; 
std::copy(str.begin(), str.end(), std::ostream_iterator<MyReplacer>(oss)); 
std::string result = oss.str(); 
16

Bạn có thể sử dụng các thuật toán tiêu chuẩn replace_if, ngoại trừ vị là khá phức tạp (được thể hiện nội tuyến với C++ hiện tại tiêu chuẩn và không lambda).

Bạn có thể viết riêng của bạn, hoặc sử dụng các thuật toán is_any_of từ chuỗi tăng, vì vậy:

#include <algorithm> 
#include <string> 
#include <boost/algorithm/string/classification.hpp> 
#include <iostream> 

int main() 
{ 
    std::string s("This,Is A|Test"); 
    std::replace_if(s.begin(), s.end(), boost::is_any_of(", |"), '_'); 
    std::cout << s << '\n'; 
} 
Các vấn đề liên quan