문자열에서 특정 문자 자르기


120

이 메서드에 해당 하는 JavaScript 는 무엇입니까?C#

var x = "|f|oo||"; 
var y = x.Trim('|'); //  "f|oo"

C # 은 문자열 의 시작 에서만 선택한 문자를 트리밍 합니다!

답변:


155

한 줄이면 충분합니다.

var x = '|f|oo||';
var y = x.replace(/^\|+|\|+$/g, '');
document.write(x + '<br />' + y);

^\|+   beginning of the string, pipe, one or more times
|      or
\|+$   pipe, one or more times, end of the string

일반적인 해결책 :

function trim (s, c) {
  if (c === "]") c = "\\]";
  if (c === "\\") c = "\\\\";
  return s.replace(new RegExp(
    "^[" + c + "]+|[" + c + "]+$", "g"
  ), "");
}

chars = ".|]\\";
for (c of chars) {
  s = c + "foo" + c + c + "oo" + c + c + c;
  console.log(s, "->", trim(s, c));
}


35

내가 잘 이해했다면 특정 문자가 문자열의 시작 또는 끝에있는 경우에만 제거하고 싶습니다 (예 : ||fo||oo||||가되어야 함 foo||oo). 다음과 같이 임시 기능을 생성 할 수 있습니다.

function trimChar(string, charToRemove) {
    while(string.charAt(0)==charToRemove) {
        string = string.substring(1);
    }

    while(string.charAt(string.length-1)==charToRemove) {
        string = string.substring(0,string.length-1);
    }

    return string;
}

아래 코드로이 기능을 테스트했습니다.

var str = "|f|oo||";
$( "#original" ).html( "Original String: '" + str + "'" );
$( "#trimmed" ).html( "Trimmed: '" + trimChar(str, "|") + "'" );

3
이것은 가비지 컬렉터에 대한 재미있는 테스트가 될 수 있지만 클라이언트를 대상으로하는 것은 권장하지 않습니다.
Sorensen

18

다음과 같은 정규식을 사용할 수 있습니다.

var x = "|f|oo||";
var y = x.replace(/^[\|]+|[\|]+$/g, "");
alert(y); // f|oo

최신 정보:

이것을 함수로 일반화하려면 다음을 수행 할 수 있습니다.

var escapeRegExp = function(strToEscape) {
    // Escape special characters for use in a regular expression
    return strToEscape.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
};

var trimChar = function(origString, charToTrim) {
    charToTrim = escapeRegExp(charToTrim);
    var regEx = new RegExp("^[" + charToTrim + "]+|[" + charToTrim + "]+$", "g");
    return origString.replace(regEx, "");
};

var x = "|f|oo||";
var y = trimChar(x, "|");
alert(y); // f|oo

17

이 질문을 최신 상태로 유지하려면 :

여기에 ES6 스프레드 연산자를 사용하여 정규식 함수를 선택하는 방법이 있습니다.

function trimByChar(string, character) {
  const first = [...string].findIndex(char => char !== character);
  const last = [...string].reverse().findIndex(char => char !== character);
  return string.substring(first, string.length - last);
}

@fabian의 주석 이후 버전 개선 (동일한 문자 만 포함 된 문자열 처리 가능)

function trimByChar(string, character) {
  const arr = Array.from(string);
  const first = arr.indexOf(character);
  const last = arr.reverse().indexOf(character);
  return string.substring(first + 1, string.length - last - 1);
}

2
여기서 정규식이 과도하다는 것을 알고 있지만이 특정 구현을 선택하는 이유는 무엇입니까?
Nicholas Shanks 2018 년

2
이 구현은 개인적으로 쉽게 읽을 수 있기 때문입니다. 정규식 엔진 내의 결정 "트리"가 훨씬 더 크기 때문에 정규식이 없습니다. 특히 트리밍에 사용되는 정규식에는 정규식 엔진 내에서 역 추적하는 쿼리 문자가 포함되어 있기 때문입니다. 이러한 엔진은 종종 패턴을 기계 명령어와 유사한 바이트 코드로 컴파일합니다. 그런 다음 엔진은 코드를 실행하여 명령어에서 명령어로 점프합니다. 명령이 실패하면 입력과 일치하는 다른 방법을 찾기 위해 역 추적합니다. nec보다 훨씬 더 많이 진행됩니다.
Robin F.

답장을 보내 주셔서 감사합니다. 비록 정규식이 아닌 다른 방법보다 이것을 선택하는 이유를 설명해 주셨으면합니다. "나는 그것을 읽을 수 있다고 생각합니다."그 이상을 바라고있었습니다.
Nicholas Shanks

1
@RobinF. findIndex () 및 reverse ()에 루프가 없다고 생각하십니까? 다시 생각 해봐.
Andrew

1
두 가지 주석 : 트리밍 할 문자 만 포함 된 문자열은 전혀 트리밍되지 않습니다. 다른 점은 스프레드 연산자를 사용하여 문자열을 배열로 분해하면 바벨을 혼동 [].concat(string)하고 원하는 결과가 아닌 것으로 변환합니다 . 사용 Array.from(string)하면 작동합니다.
Fabian

14

보기 쉬운 정규식없는 버전 :

const trim = (str, chars) => str.split(chars).filter(Boolean).join(chars);

가장자리에서 문자가 반복되지 않는다고 확신하는 사용 사례를 위해.


매우 흥미 롭습니다. 분할은 분할 된 각 구분 기호에 대해 정의되지 않은 요소를 반환합니다.const trim = (str, chars) => str.split(chars).filter(x => { Boolean(x); console.log(typeof(x), x, Boolean(x)); }).join(chars); const str = "#//#//abc#//test#//end#//"; console.log(trim(str, '#//'));
TamusJRoyce

10

더 긴 문자열을 처리하는 경우 할당 된 문자열 수를 0 또는 1로 줄임으로써 대부분의 다른 옵션보다 성능이 우수하다고 생각합니다.

function trim(str, ch) {
    var start = 0, 
        end = str.length;

    while(start < end && str[start] === ch)
        ++start;

    while(end > start && str[end - 1] === ch)
        --end;

    return (start > 0 || end < str.length) ? str.substring(start, end) : str;
}

// Usage:
trim('|hello|world|', '|'); // => 'hello|world'

또는 여러 문자 집합에서 트리밍하려는 경우 :

function trimAny(str, chars) {
    var start = 0, 
        end = str.length;

    while(start < end && chars.indexOf(str[start]) >= 0)
        ++start;

    while(end > start && chars.indexOf(str[end - 1]) >= 0)
        --end;

    return (start > 0 || end < str.length) ? str.substring(start, end) : str;
}

// Usage:
trimAny('|hello|world   ', [ '|', ' ' ]); // => 'hello|world'
// because '.indexOf' is used, you could also pass a string for the 2nd parameter:
trimAny('|hello| world  ', '| '); // => 'hello|world'

편집 : 재미를 위해 (개별 문자가 아닌) 단어 다듬기

// Helper function to detect if a string contains another string
//     at a specific position. 
// Equivalent to using `str.indexOf(substr, pos) === pos` but *should* be more efficient on longer strings as it can exit early (needs benchmarks to back this up).
function hasSubstringAt(str, substr, pos) {
    var idx = 0, len = substr.length;

    for (var max = str.length; idx < len; ++idx) {
        if ((pos + idx) >= max || str[pos + idx] != substr[idx])
            break;
    }

    return idx === len;
}

function trimWord(str, word) {
    var start = 0,
        end = str.length,
        len = word.length;

    while (start < end && hasSubstringAt(str, word, start))
        start += word.length;

    while (end > start && hasSubstringAt(str, word, end - len))
        end -= word.length

    return (start > 0 || end < str.length) ? str.substring(start, end) : str;
}

// Usage:
trimWord('blahrealmessageblah', 'blah');

1
저는이 솔루션이 실제로 짧기보다는 효율적이기 때문에 선호합니다.
tekHedd

선호해야한다는 데 동의합니다. 내가 준 대답을 대체합니다.
TamusJRoyce

9

이렇게하면 한 번에 여러 문자를자를 수 있습니다.

String.prototype.trimChars = function (c) {
  var re = new RegExp("^[" + c + "]+|[" + c + "]+$", "g");
  return this.replace(re,"");
}

var x = "|f|oo||"; 
x =  x.trimChars('|'); // f|oo

var y = "..++|f|oo||++..";
y = y.trimChars('|.+'); // f|oo

var z = "\\f|oo\\"; // \f|oo\

// For backslash, remember to double-escape:
z = z.trimChars("\\\\"); // f|oo

@fubo : 아니요, 정말 아닙니다. 데모입니다. 콘솔에 붙여 넣으면 결과 만 출력됩니다. 그러나 혼란 스러울 수 있음을 이해하여 편집했습니다.
marlar

2

프로그램에서 이러한 함수를 정의하면 문자열은 trim주어진 모든 문자를자를 수 있는 업그레이드 된 버전을 갖게됩니다 .

String.prototype.trimLeft = function(charlist) {
	if (charlist === undefined)
	charlist = "\s";

	return this.replace(new RegExp("^[" + charlist + "]+"), "");
};

String.prototype.trim = function(charlist) {
	return this.trimLeft(charlist).trimRight(charlist);
};

String.prototype.trimRight = function(charlist) {
	if (charlist === undefined)
	charlist = "\s";

	return this.replace(new RegExp("[" + charlist + "]+$"), "");
};

var withChars = "/-center-/"
var withoutChars = withChars.trim("/-")
document.write(withoutChars)

출처

https://www.sitepoint.com/trimming-strings-in-javascript/


1

내가 아는 한, jQuery에는 귀하가 요청하는 방법이 내장 된 기능이 없습니다. 그러나 javascript를 사용하면 replace를 사용하여 문자열의 내용을 변경할 수 있습니다.

x.replace(/|/i, ""));

이것은 | 아무것도없이.


제거하는 방법이 있습니까 | 시작 / 끝에 만?
푸보

: 사실이 게시물은 당신에게 당신의 질문에 속도에 가장 얻을 것이라고 생각 stackoverflow.com/questions/20196088/...
올레 Haugset

@fubo 물론 이죠 ... $끝에서만 이런 식으로 던지 "||spam|||".replace(/\|+$/g, "")거나 ^시작시에만 이런 식으로 :"||spam|||".replace(/^\|+/g, "")
ruffin

1

이것은 모든 선행 및 후행 구분자를 트리밍합니다.

const trim = (str, delimiter) => {
  const pattern = `[^\\${delimiter}]`;
  const start = str.search(pattern);
  const stop = str.length - str.split('').reverse().join('').search(pattern);
  return str.substring(start, stop);
}

const test = '||2|aaaa12bb3ccc|||||';
console.log(trim(test, '|')); // 2|aaaa12bb3ccc

1

lodash를 살펴보고 어떻게 구현했는지 trim 기능 합니다.

문서 및 소스Lodash Trim 을 참조하십시오. 트리밍을 수행하는 정확한 코드를 볼 수 있습니다.

나는 이것이 귀하의 질문에 정확한 답을 제공하지 않는다는 것을 알고 있지만 다른 사람들이 유용하다고 생각할 수 있으므로 그러한 질문에 대한 라이브러리에 대한 참조를 설정하는 것이 좋습니다.


1
@TamusJRoyce는 동일하지 않습니다
gdbdable

@devi 나는 동의 할 수 있습니다. 댓글 주셔서 감사합니다. 커뮤니티 지원 도구를 살펴 보는 좋은 답변입니다.
TamusJRoyce

1

이 작업을 해결하는 가장 좋은 방법은 다음과 같습니다 (PHP trim함수 와 유사 ).

function trim( str, charlist ) {
  if ( typeof charlist == 'undefined' ) {
    charlist = '\\s';
  }
  
  var pattern = '^[' + charlist + ']*(.*?)[' + charlist + ']*$';
  
  return str.replace( new RegExp( pattern ) , '$1' )
}

document.getElementById( 'run' ).onclick = function() {
  document.getElementById( 'result' ).value = 
  trim( document.getElementById( 'input' ).value,
  document.getElementById( 'charlist' ).value);
}
<div>
  <label for="input">Text to trim:</label><br>
  <input id="input" type="text" placeholder="Text to trim" value="dfstextfsd"><br>
  <label for="charlist">Charlist:</label><br>
  <input id="charlist" type="text" placeholder="Charlist" value="dfs"><br>
  <label for="result">Result:</label><br>
  <input id="result" type="text" placeholder="Result" disabled><br>
  <button type="button" id="run">Trim it!</button>
</div>

추신 : 대부분의 사람들이 이전에 이미 답변을했는데 왜 제가 답변을 게시 했습니까? 모든 답변에서 "가장 좋은"실수를 발견했기 때문에 모두 '*'대신 '+'메타를 사용했습니다. ' trim시작 및 / 또는 끝에 있으면 문자를 제거해야하지만 그렇지 않으면 원래 문자열을 반환합니다. .


0

@leaf의 답변을 확장하면 여러 문자를 사용할 수있는 답변이 있습니다.

var trim = function (s, t) {
  var tr, sr
  tr = t.split('').map(e => `\\\\${e}`).join('')
  sr = s.replace(new RegExp(`^[${tr}]+|[${tr}]+$`, 'g'), '')
  return sr
}

0

@ Pho3niX83의 솔루션이 마음에 듭니다 ...

"char"대신 "word"로 확장 해 봅시다 ...

function trimWord(_string, _word) {

    var splitted = _string.split(_word);

    while (splitted.length && splitted[0] === "") {
        splitted.shift();
    }
    while (splitted.length && splitted[splitted.length - 1] === "") {
        splitted.pop();
    }
    return splitted.join(_word);
};




-1
String.prototype.TrimStart = function (n) {
    if (this.charAt(0) == n)
        return this.substr(1);
};

String.prototype.TrimEnd = function (n) {
    if (this.slice(-1) == n)
        return this.slice(0, -1);
};

그것은 단지 하나 명의 발생을 제거 할 수 있지만 문자가 완전히 손질 될 때까지 트림하지 않습니다
KoalaBear

1
기본 문자열 프로토 타입을 재정의하지 마십시오. 그렇지 않으면 나중에 문제가 발생합니다. 다른 곳에서 자신 만의 별도 함수를 만듭니다.
rooby

-2

이 방법을 시도하십시오.

var a = "anan güzel mi?";
if (a.endsWith("?"))   a = a.slice(0, -1);  
document.body.innerHTML = a;


1
왜? 이것은 무엇을합니까? 어떻게 작동합니까? 코드 전용 답변은 SO에서 낮은 품질로 간주됩니다. OP와 향후 방문자가 학습 할 수 있도록 답변을 설명하세요.
당황하지 마십시오
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.