문자열에서 선행 및 후행 공백 제거
C ++의 문자열 개체에서 공백을 제거하는 방법.
예를 들어, 아래 문자열 객체에서 선행 및 후행 공백을 제거하는 방법.
//Original string: " This is a sample string "
//Desired string: "This is a sample string"
내가 아는 한 문자열 클래스는 선행 및 후행 공백을 제거하는 방법을 제공하지 않습니다.
문제를 추가하려면이 서식을 확장하여 문자열의 단어 사이에 추가 공백을 처리하는 방법입니다. 예를 들면
// Original string: " This is a sample string "
// Desired string: "This is a sample string"
솔루션에 언급 된 문자열 메서드를 사용하여 이러한 작업을 두 단계로 수행하는 것을 생각할 수 있습니다.
- 선행 및 후행 공백을 제거하십시오.
- 원하는 형식을 얻으려면 단어 경계에서 find_first_of, find_last_of, find_first_not_of, find_last_not_of 및 substr 을 반복적으로 사용하십시오 .
이를 트리밍이라고합니다. Boost 를 사용할 수 있다면 추천합니다.
그렇지 않으면을 사용 find_first_not_of
하여 공백이 아닌 첫 번째 문자 find_last_not_of
의 인덱스를 가져온 다음 공백이 아닌 끝에서 인덱스를 가져옵니다. 이를 사용 substr
하여 주변 공백이없는 하위 문자열을 가져옵니다.
당신의 편집에 대한 응답으로, 나는 용어를 모르지만 "축소"라는 줄을 따라 무언가를 추측 할 것입니다. 그래서 그것을 제가 부르는 것입니다. :) (참고, 유연성을 위해 공백을 매개 변수로 변경했습니다.)
#include <iostream>
#include <string>
std::string trim(const std::string& str,
const std::string& whitespace = " \t")
{
const auto strBegin = str.find_first_not_of(whitespace);
if (strBegin == std::string::npos)
return ""; // no content
const auto strEnd = str.find_last_not_of(whitespace);
const auto strRange = strEnd - strBegin + 1;
return str.substr(strBegin, strRange);
}
std::string reduce(const std::string& str,
const std::string& fill = " ",
const std::string& whitespace = " \t")
{
// trim first
auto result = trim(str, whitespace);
// replace sub ranges
auto beginSpace = result.find_first_of(whitespace);
while (beginSpace != std::string::npos)
{
const auto endSpace = result.find_first_not_of(whitespace, beginSpace);
const auto range = endSpace - beginSpace;
result.replace(beginSpace, range, fill);
const auto newStart = beginSpace + fill.length();
beginSpace = result.find_first_of(whitespace, newStart);
}
return result;
}
int main(void)
{
const std::string foo = " too much\t \tspace\t\t\t ";
const std::string bar = "one\ntwo";
std::cout << "[" << trim(foo) << "]" << std::endl;
std::cout << "[" << reduce(foo) << "]" << std::endl;
std::cout << "[" << reduce(foo, "-") << "]" << std::endl;
std::cout << "[" << trim(bar) << "]" << std::endl;
}
결과:
[too much space]
[too much space]
[too-much-space]
[one
two]
한 줄로 std :: string에서 선행, 후행 및 추가 공백을 쉽게 제거
value = std::regex_replace(value, std::regex("^ +| +$|( ) +"), "$1");
선행 공백 만 제거
value.erase(value.begin(), std::find_if(value.begin(), value.end(), std::bind1st(std::not_equal_to<char>(), ' ')));
또는
value = std::regex_replace(value, std::regex("^ +"), "");
후행 공백 만 제거
value.erase(std::find_if(value.rbegin(), value.rend(), std::bind1st(std::not_equal_to<char>(), ' ')).base(), value.end());
또는
value = std::regex_replace(value, std::regex(" +$"), "");
여분의 공백 만 제거
value = regex_replace(value, std::regex(" +"), " ");
현재 다음 기능을 사용하고 있습니다.
// trim from left
inline std::string& ltrim(std::string& s, const char* t = " \t\n\r\f\v")
{
s.erase(0, s.find_first_not_of(t));
return s;
}
// trim from right
inline std::string& rtrim(std::string& s, const char* t = " \t\n\r\f\v")
{
s.erase(s.find_last_not_of(t) + 1);
return s;
}
// trim from left & right
inline std::string& trim(std::string& s, const char* t = " \t\n\r\f\v")
{
return ltrim(rtrim(s, t), t);
}
// copying versions
inline std::string ltrim_copy(std::string s, const char* t = " \t\n\r\f\v")
{
return ltrim(s, t);
}
inline std::string rtrim_copy(std::string s, const char* t = " \t\n\r\f\v")
{
return rtrim(s, t);
}
inline std::string trim_copy(std::string s, const char* t = " \t\n\r\f\v")
{
return trim(s, t);
}
#include <boost/algorithm/string/trim.hpp>
[...]
std::string msg = " some text with spaces ";
boost::algorithm::trim(msg);
방법은 다음과 같습니다.
std::string & trim(std::string & str)
{
return ltrim(rtrim(str));
}
그리고 지원 기능은 다음과 같이 구현됩니다.
std::string & ltrim(std::string & str)
{
auto it2 = std::find_if( str.begin() , str.end() , [](char ch){ return !std::isspace<char>(ch , std::locale::classic() ) ; } );
str.erase( str.begin() , it2);
return str;
}
std::string & rtrim(std::string & str)
{
auto it1 = std::find_if( str.rbegin() , str.rend() , [](char ch){ return !std::isspace<char>(ch , std::locale::classic() ) ; } );
str.erase( it1.base() , str.end() );
return str;
}
이 모든 것이 제자리에 있으면 다음과 같이 작성할 수 있습니다.
std::string trim_copy(std::string const & str)
{
auto s = str;
return ltrim(rtrim(s));
}
이 시도
부스트를 사용하라는 jon-hanson의 제안에 따라 선행 및 후행 공백을 자르는 예 (후행 및 보류중인 공백 만 제거) :
#include <boost/algorithm/string/trim.hpp>
std::string str = " t e s t ";
boost::algorithm::trim ( str );
결과 "t e s t"
도 있습니다
trim_left
결과"t e s t "
trim_right
결과" t e s t"
이것은 선행 및 후행 공백을 제거하는 솔루션입니다 ...
std::string stripString = " Plamen ";
while(!stripString.empty() && std::isspace(*stripString.begin()))
stripString.erase(stripString.begin());
while(!stripString.empty() && std::isspace(*stripString.rbegin()))
stripString.erase(stripString.length()-1);
결과는 "Plamen"입니다.
/// strip a string, remove leading and trailing spaces
void strip(const string& in, string& out)
{
string::const_iterator b = in.begin(), e = in.end();
// skipping leading spaces
while (isSpace(*b)){
++b;
}
if (b != e){
// skipping trailing spaces
while (isSpace(*(e-1))){
--e;
}
}
out.assign(b, e);
}
위 코드에서 isSpace () 함수는 문자가 공백인지 여부를 알려주는 부울 함수입니다.이 함수를 구현하여 필요를 반영하거나 원하는 경우 "ctype.h"에서 isspace ()를 호출 할 수 있습니다. .
표준 라이브러리를 사용하면 많은 이점이 있지만 예외를 발생시키는 몇 가지 특별한 경우를 알고 있어야합니다. 예를 들어, C ++ 문자열에 유니 코드 문자가있는 경우에 대한 답변은 없습니다. 이 경우 isspace 함수를 사용하면 예외가 발생합니다.
다음 코드를 사용하여 문자열 및 유용한 기타 작업을 다듬 었습니다. 이 코드의 주요 이점은 다음과 같습니다. 정말 빠르며 (내가 테스트 한 어떤 코드보다 빠름) 표준 라이브러리 만 사용하며 예외가 발생하지 않습니다.
#include <string>
#include <algorithm>
#include <functional>
#include <locale>
#include <iostream>
typedef unsigned char BYTE;
std::string strTrim(std::string s, char option = 0)
{
// convert all whitespace characters to a standard space
std::replace_if(s.begin(), s.end(), (std::function<int(BYTE)>)::isspace, ' ');
// remove leading and trailing spaces
size_t f = s.find_first_not_of(' ');
if (f == std::string::npos) return "";
s = s.substr(f, s.find_last_not_of(' ') - f + 1);
// remove consecutive spaces
s = std::string(s.begin(), std::unique(s.begin(), s.end(),
[](BYTE l, BYTE r){ return l == ' ' && r == ' '; }));
switch (option)
{
case 'l': // convert to lowercase
std::transform(s.begin(), s.end(), s.begin(), ::tolower);
return s;
case 'U': // convert to uppercase
std::transform(s.begin(), s.end(), s.begin(), ::toupper);
return s;
case 'n': // remove all spaces
s.erase(std::remove(s.begin(), s.end(), ' '), s.end());
return s;
default: // just trim
return s;
}
}
선행 및 후행 공백 자르기의 예
std::string aString(" This is a string to be trimmed ");
auto start = aString.find_first_not_of(' ');
auto end = aString.find_last_not_of(' ');
std::string trimmedString;
trimmedString = aString.substr(start, (end - start) + 1);
또는
trimmedSring = aString.substr(aString.find_first_not_of(' '), (aString.find_last_not_of(' ') - aString.find_first_not_of(' ')) + 1);
나는 이것을 테스트했으며 모두 작동합니다. 따라서 processInput 메소드는 사용자에게 무언가를 입력하도록 요청합니다. 내부적으로 추가 공백이없고 시작 또는 끝에 추가 공백이없는 문자열을 반환합니다. 도움이 되었기를 바랍니다. (또한 이해하기 쉽도록 많은 주석을 추가하십시오).
하단의 main ()에서 구현하는 방법을 볼 수 있습니다.
#include <string>
#include <iostream>
string processInput() {
char inputChar[256];
string output = "";
int outputLength = 0;
bool space = false;
// user inputs a string.. well a char array
cin.getline(inputChar,256);
output = inputChar;
string outputToLower = "";
// put characters to lower and reduce spaces
for(int i = 0; i < output.length(); i++){
// if it's caps put it to lowercase
output[i] = tolower(output[i]);
// make sure we do not include tabs or line returns or weird symbol for null entry array thingy
if (output[i] != '\t' && output[i] != '\n' && output[i] != 'Ì') {
if (space) {
// if the previous space was a space but this one is not, then space now is false and add char
if (output[i] != ' ') {
space = false;
// add the char
outputToLower+=output[i];
}
} else {
// if space is false, make it true if the char is a space
if (output[i] == ' ') {
space = true;
}
// add the char
outputToLower+=output[i];
}
}
}
// trim leading and tailing space
string trimmedOutput = "";
for(int i = 0; i < outputToLower.length(); i++){
// if it's the last character and it's not a space, then add it
// if it's the first character and it's not a space, then add it
// if it's not the first or the last then add it
if (i == outputToLower.length() - 1 && outputToLower[i] != ' ' ||
i == 0 && outputToLower[i] != ' ' ||
i > 0 && i < outputToLower.length() - 1) {
trimmedOutput += outputToLower[i];
}
}
// return
output = trimmedOutput;
return output;
}
int main() {
cout << "Username: ";
string userName = processInput();
cout << "\nModified Input = " << userName << endl;
}
이것은 가장 간단한 것일 수 있습니다.
당신은 사용할 수 있습니다 string::find
및 string::rfind
양쪽에서 공백 발견하고 문자열을 줄일 수 있습니다.
void TrimWord(std::string& word)
{
if (word.empty()) return;
// Trim spaces from left side
while (word.find(" ") == 0)
{
word.erase(0, 1);
}
// Trim spaces from right side
size_t len = word.size();
while (word.rfind(" ") == --len)
{
word.erase(len, len + 1);
}
}
왜 복잡합니까?
std::string removeSpaces(std::string x){
if(x[0] == ' '){ x.erase(0, 1); }
if(x[x.length()-1] == ' '){ x.erase(x.length()-1, x.length()); }
return x;
}
부스트가 실패하고 정규식이없고 이상한 물건이나 라이브러리가 없어도 작동합니다.
char *str = (char*) malloc(50 * sizeof(char));
strcpy(str, " some random string (<50 chars) ");
while(*str == ' ' || *str == '\t' || *str == '\n')
str++;
int len = strlen(str);
while(len >= 0 &&
(str[len - 1] == ' ' || str[len - 1] == '\t' || *str == '\n')
{
*(str + len - 1) = '\0';
len--;
}
printf(":%s:\n", str);
void removeSpaces(string& str)
{
/* remove multiple spaces */
int k=0;
for (int j=0; j<str.size(); ++j)
{
if ( (str[j] != ' ') || (str[j] == ' ' && str[j+1] != ' ' ))
{
str [k] = str [j];
++k;
}
}
str.resize(k);
/* remove space at the end */
if (str [k-1] == ' ')
str.erase(str.end()-1);
/* remove space at the begin */
if (str [0] == ' ')
str.erase(str.begin());
}
string trim(const string & sStr)
{
int nSize = sStr.size();
int nSPos = 0, nEPos = 1, i;
for(i = 0; i< nSize; ++i) {
if( !isspace( sStr[i] ) ) {
nSPos = i ;
break;
}
}
for(i = nSize -1 ; i >= 0 ; --i) {
if( !isspace( sStr[i] ) ) {
nEPos = i;
break;
}
}
return string(sStr, nSPos, nEPos - nSPos + 1);
}
선행 및 후행 공백의 경우 다음은 어떻습니까?
string string_trim(const string& in) {
stringstream ss;
string out;
ss << in;
ss >> out;
return out;
}
또는 문장 :
string trim_words(const string& sentence) {
stringstream ss;
ss << sentence;
string s;
string out;
while(ss >> s) {
out+=(s+' ');
}
return out.substr(0, out.length()-1);
}
청초한
void trimLeftTrailingSpaces(string &input) {
input.erase(input.begin(), find_if(input.begin(), input.end(), [](int ch) {
return !isspace(ch);
}));
}
void trimRightTrailingSpaces(string &input) {
input.erase(find_if(input.rbegin(), input.rend(), [](int ch) {
return !isspace(ch);
}).base(), input.end());
}
아니 boost
, 아니 regex
, 그냥 string
도서관. 그렇게 간단합니다.
string trim(const string s) { // removes whitespace characters from beginnig and end of string s
string x = s;
for(int i=0; i<(int)s.length(); i++) {
const int l = (int)x.length()-1;
if(x[l]==' '||x[l]=='\t'||x[l]=='\n'||x[l]=='\v'||x[l]=='\f'||x[l]=='\r'||x[l]=='\0') x.erase(l, 1);
if(x[0]==' '||x[0]=='\t'||x[0]=='\n'||x[0]=='\v'||x[0]=='\f'||x[0]=='\r'||x[0]=='\0') x.erase(0, 1);
}
return x;
}
무엇에 대한 삭제 - 제거 관용구 ?
std::string s("...");
s.erase( std::remove(s.begin(), s.end(), ' '), s.end() );
죄송합니다. 공백을 모두 제거하고 싶지 않다는 것을 너무 늦게 보았습니다 .
STL 메서드를 사용하지 않고 C ++ 문자열 자체 메서드 만 사용하는이 문제에 대한 내 솔루션은 다음과 같습니다.
void processString(string &s) {
if ( s.empty() ) return;
//delete leading and trailing spaces of the input string
int notSpaceStartPos = 0, notSpaceEndPos = s.length() - 1;
while ( s[notSpaceStartPos] == ' ' ) ++notSpaceStartPos;
while ( s[notSpaceEndPos] == ' ' ) --notSpaceEndPos;
if ( notSpaceStartPos > notSpaceEndPos ) { s = ""; return; }
s = s.substr(notSpaceStartPos, notSpaceEndPos - notSpaceStartPos + 1);
//reduce multiple spaces between two words to a single space
string temp;
for ( int i = 0; i < s.length(); i++ ) {
if ( i > 0 && s[i] == ' ' && s[i-1] == ' ' ) continue;
temp.push_back(s[i]);
}
s = temp;
}
이 방법을 사용하여 LeetCode 문제를 전달 했습니다. 문자열에서 단어 반전
void TrimWhitespaces(std::wstring& str)
{
if (str.empty())
return;
const std::wstring& whitespace = L" \t";
std::wstring::size_type strBegin = str.find_first_not_of(whitespace);
std::wstring::size_type strEnd = str.find_last_not_of(whitespace);
if (strBegin != std::wstring::npos || strEnd != std::wstring::npos)
{
strBegin == std::wstring::npos ? 0 : strBegin;
strEnd == std::wstring::npos ? str.size() : 0;
const auto strRange = strEnd - strBegin + 1;
str.substr(strBegin, strRange).swap(str);
}
else if (str[0] == ' ' || str[0] == '\t') // handles non-empty spaces-only or tabs-only
{
str = L"";
}
}
void TrimWhitespacesTest()
{
std::wstring EmptyStr = L"";
std::wstring SpacesOnlyStr = L" ";
std::wstring TabsOnlyStr = L" ";
std::wstring RightSpacesStr = L"12345 ";
std::wstring LeftSpacesStr = L" 12345";
std::wstring NoSpacesStr = L"12345";
TrimWhitespaces(EmptyStr);
TrimWhitespaces(SpacesOnlyStr);
TrimWhitespaces(TabsOnlyStr);
TrimWhitespaces(RightSpacesStr);
TrimWhitespaces(LeftSpacesStr);
TrimWhitespaces(NoSpacesStr);
assert(EmptyStr == L"");
assert(SpacesOnlyStr == L"");
assert(TabsOnlyStr == L"");
assert(RightSpacesStr == L"12345");
assert(LeftSpacesStr == L"12345");
assert(NoSpacesStr == L"12345");
}
참고 URL : https://stackoverflow.com/questions/1798112/removing-leading-and-trailing-spaces-from-a-string
'Nice programing' 카테고리의 다른 글
Htaccess : URL에서 후행 슬래시 추가 / 제거 (0) | 2020.10.22 |
---|---|
기호를 찾을 수 없음 : __PyCodecInfo_GetIncrementalDecoder (0) | 2020.10.22 |
CloudFlare 및 PHP를 통해 방문자 IP 주소 로깅 (0) | 2020.10.22 |
컴파일 타임에 런타임 다형성을 해결할 수없는 이유는 무엇입니까? (0) | 2020.10.22 |
Facebook SDK : URL 체계로 등록되지 않은 앱 (0) | 2020.10.22 |