JavaScript에서 특정 색인의 문자를 바꾸려면 어떻게해야합니까?


544

문자열을 가지고 있다고 가정 해 봅시다 Hello world. 색인 3에서 문자를 바꿔야합니다. 색인을 지정하여 문자를 바꾸려면 어떻게해야합니까?

var str = "hello world";

나는 같은 것이 필요하다

str.replaceAt(0,"h");

131
이상한 점 str[0] = 'x'은 오류가 발생하지 않지만 원하는 효과가 없다는 것입니다!
Michael

6
@Michael을 사용하면 인덱스를 0으로 설정하고 'x'로 설정하면 해당 명령문 자체가 새 값을 반환합니다. '엑스'. 그러나 모든 것이 오리지널을 변경하지 않으므로 완벽하게 유효합니다. 예상 한 것이 아닙니다. 참조가 아닙니다
Paul Scheltema

8
@Michael "use strict"활성화 된 경우 Uncaught TypeError: Cannot assign to read only property '0' of string 'hello world'(적어도 웹킷 브라우저에서)
Jan Turoň

1
Javascript 문자열은 변경할 수 없으므로 "제자리에서"수정할 수 없으므로 단일 문자를 수정할 수 없습니다. 실제로 동일한 문자열의 모든 발생은 하나의 객체입니다.
Martijn Scheffer

좋아, 답변을 참조하십시오 : D
Martijn Scheffer

답변:


611

JavaScript에서 문자열은 변경할 수 없으므로 변경된 내용으로 새 문자열을 만들고 변수를 지정하도록 지정하는 것이 최선의 방법입니다.

replaceAt()함수를 직접 정의해야합니다 .

String.prototype.replaceAt = function(index, replacement) {
    return this.substr(0, index) + replacement + this.substr(index + replacement.length);
}

그리고 이것을 다음과 같이 사용하십시오 :

var hello = "Hello World";
alert(hello.replaceAt(2, "!!")); // Should display He!!o World

101
기본 JavaScript 클래스를 확장하는 것은 일반적으로 좋은 생각이 아닙니다. 대신 일반 유틸리티 기능을 사용하십시오.
Ates Goral

86
왜 그런지 물어봐야합니까? 이 목적을 위해 프로토 타입 지원이 있습니다.
Cem Kalyoncu

30
@CemKalyoncu : 다른 라이브러리에서는 코드가 잘못 재생 될 수 있습니다 . 그러나 나는 그 자신에게 물린 적이 없습니다.
alex

6
@ alex : 맞습니다. 실제로 기능이 있는지 확인해야합니다. 그러나 여전히 그렇더라도 정확히 동일한 작업을 수행해야합니다.
Cem Kalyoncu

80
함수가 존재하는지 여부를 감지하더라도 나중에 라이브러리가 여전히 비슷한 함수를 사용하거나 만들 수 있습니다. 일반적으로 다른 사람들의 코드 (핵심 시스템 포함)를 다루지 마십시오. 새로운 기능을 만듭니다.
순교자

93

replaceAtJavaScript 에는 기능 이 없습니다 . 다음 코드를 사용하여 지정된 위치에있는 문자열의 모든 문자를 바꿀 수 있습니다.

function rep() {
    var str = 'Hello World';
    str = setCharAt(str,4,'a');
    alert(str);
}

function setCharAt(str,index,chr) {
    if(index > str.length-1) return str;
    return str.substr(0,index) + chr + str.substr(index+1);
}
<button onclick="rep();">click</button>



단일 문자를 대체 할 수 있기 때문에이 솔루션을 선호합니다. 하나의 문자 만 바꾸려는 경우 가장 많이 투표 한 솔루션이 작동하지 않습니다. 두 문자를 교체 할 때만 작동합니다! 또한 많은 다른 주석에서 언급했듯이 substr은 substring으로 대체되어야합니다.
gignu

74

당신은 할 수 없습니다. 위치 전후의 문자를 사용하여 새 문자열로 연결하십시오.

var s = "Hello world";
var index = 3;
s = s.substring(0, index) + 'x' + s.substring(index + 1);

사실, 그렇습니다, 그러나 그것은 과잉 일 것입니다. 정규식을 설정하여 첫 번째 색인-1자를 건너 뛰고 색인의 문자를 일치시킬 수 있습니다. String.replace를 해당 정규식과 함께 사용하여 직접 대체 할 수 있습니다. 그러나 그것은 과잉입니다. 실제로는 할 수 없습니다. 그러나 이론 상으로는 가능합니다.
Ates Goral

12
@Ates : replace 함수는 전체 대체를 수행하지 않고 새 문자열을 만들어 반환합니다.
Guffa September

2
MDN 은을 (를) 사용 String.prototype.substring하는 것이 좋습니다 String.prototype.substr.
Mikemike

33

여기에 많은 답변이 있으며 모두 두 가지 방법을 기반으로합니다.

  • 방법 1 : 두 개의 하위 문자열을 사용하여 문자열을 분할하고 그 사이에 문자를 넣습니다.
  • METHOD2 : 문자열을 문자형 배열로 변환하고 하나의 배열 구성원을 대체하여 결합

개인적으로, 나는이 두 가지 방법을 다른 경우에 사용할 것입니다. 설명하겠습니다.

@ FabioPhms : 귀하의 방법은 처음에 사용한 방법이며 많은 문자가있는 문자열이 나쁘다는 것을 두려워했습니다. 그러나 질문은 많은 캐릭터가 무엇입니까? 10 개의 "lorem ipsum"단락에서 테스트했으며 몇 밀리 초가 걸렸습니다. 그런 다음 10 배 큰 문자열로 테스트했습니다. 큰 차이는 없었습니다. 흠.

@vsync, @Cory Mawhorter : 귀하의 의견은 모호하지 않습니다. 그러나 다시 큰 문자열은 무엇입니까? 32 ... 100kb의 성능이 향상되고 문자 교체 작업 하나에 하위 문자열 변형을 사용해야한다는 데 동의합니다.

그러나 약간의 교체 작업을 수행하면 어떻게됩니까?

그 경우 더 빠른 것을 증명하기 위해 자체 테스트를 수행해야했습니다. 1000 자로 구성된 비교적 짧은 문자열을 조작하는 알고리즘이 있다고 가정 해 봅시다. 평균적으로 해당 문자열의 각 문자는 ~ 100 배로 바뀔 것으로 예상됩니다. 따라서 다음과 같이 테스트하는 코드는 다음과 같습니다.

var str = "... {A LARGE STRING HERE} ...";

for(var i=0; i<100000; i++)
{
  var n = '' + Math.floor(Math.random() * 10);
  var p = Math.floor(Math.random() * 1000);
  // replace character *n* on position *p*
}

나는 이것을 위해 바이올린을 만들었고 여기 있습니다 . TEST1 (하위 문자열)과 TEST2 (배열 변환)의 두 가지 테스트가 있습니다.

결과 :

  • 테스트 1 : 195ms
  • 테스트 2 : 6ms

배열 변환이 하위 문자열보다 2 배 더 큰 것 같습니다! 그래서-도대체 여기서 무슨 일이 있었나요 ???

실제로 일어나는 일은 TEST2의 모든 연산이와 같은 할당 표현식을 사용하여 배열 자체에서 수행된다는 것 strarr2[p] = n입니다. 할당은 큰 문자열의 하위 문자열과 비교할 때 실제로 빠르며 승리 할 것입니다.

따라서 작업에 적합한 도구를 선택하는 것이 중요합니다. 다시.


7
jsperf.com/string-replace-character와 매우 다른 결과로 테스트를 jsperf로 옮겼 습니다 . 작업에 적합한 도구를 선택하는 것이 전부입니다.)
colllin

1
@ colllin : 나는 전적으로 동의합니다. 그래서 거의 문자 그대로 jsfiddle에서 jsperf로 테스트를 복제했습니다. 그러나 올바른 도구를 사용하는 것 외에도 올바른 방법으로 사용해야합니다. 이 문제에주의를 기울이고 알고리즘에서 몇 가지를 교체해야 할 경우 어떻게 될지 이야기하고 있습니다. 구체적인 예에는 10000 개의 교체가 포함됩니다. 즉, 한 번의 테스트 에는 10000 개의 교체가 포함되어야합니다. 따라서 jsperf를 사용하여 꽤 일관된 결과를 얻었습니다. jsperf.com/…을 참조하십시오 .
OzrenTkalcecKrznaric

1
이것이 내가 자바 스크립트를 좋아하지 않는 이유입니다. 이러한 빈번하고 직관적이며 명확한 사용 사례는 제공되지 않습니다. 사람들이 문자열 내에서 문자를 대체하고 싶을 때 편리한 방법을 언어에 넣기로 결정한 것이 자바 스크립트 작성자에게 일어날 것이라고 생각할 것입니다.
ahnbizcad

1
@colllin은 OzrenTkalcecKrznaric과는 다른 것을했습니다. OzrenTkalcecKrznaric은 문자열이 정적이며 실행 전에 분할을 최적화 할 수 있다고 가정했습니다. 반드시 그런 것은 아닙니다. 매 실행마다 분할 해야하는 경우 하위 문자열 접근 방식은 작은 문자열에서 약 2-4 배 빠르며 문자열이 커질수록 더 빠릅니다. 내 생각에 이것은 하위 문자열을 대부분의 사용 사례에서 더 나은 구현으로 만들고 큰 정적 문자열에서 많은 수의 변경을 허용하지 않습니다.
WiR3D

3
문제는 test2에서 분할 및 조인이 for 루프 외부에 있다는 것입니다. 단일 문자 교체를 여러 문자 (불공평 한)와 비교하면 첫 번째 방법은 단일 교체에 더 빠르며 두 번째 방법은 체인 교체에 대해 더 좋습니다
Θεόφιλος Μουρατίδης

32

벡터를 사용한 작업은 일반적으로 문자열에 가장 효과적입니다.

다음 기능을 제안합니다.

String.prototype.replaceAt=function(index, char) {
    var a = this.split("");
    a[index] = char;
    return a.join("");
}

이 스 니펫을 실행하십시오.

String.prototype.replaceAt=function(index, char) {
    var a = this.split("");
    a[index] = char;
    return a.join("");
}

var str = "hello world";
str = str.replaceAt(3, "#");

document.write(str);


9
이것은 큰 문자열에는 좋지 않습니다. substr을 사용하여 잘라낼 수 있다면 셀이 많은 양의 배열을 만들 필요가 없습니다.
vsync

1
많은 문자를 변경해야하는 경우에 유용하며 간단합니다.
Sheepy

6
jsperf에 대한 테스트를 만들었습니다 : jsperf.com/replace-character-by-index-Substr 은 훨씬 빠르며 32 바이트에서 최대 100kb까지 일관됩니다. 나는 이것을 높이고 말을 아프게하는 것처럼, 비록 이것이 더 좋게 느껴지더라도 substr은 어떤 크기의 문자열에도 더 나은 선택입니다.
Cory Mawhorter

이것은 매우 낙관적입니다.
Radko Dinev

작은 문자열을 사용한다는 것을 알고 있다면 좋은 빠른 솔루션입니다. 프로토 타입을 확장해도 괜찮다면 두 줄로 비슷한 동작을 할 수 있습니다.Array.prototype.replace = function(index, val) { this[index] = val; return this; }; 'word'.split('').replace(1, '0').join(''); // returns 'w0rd'
Michael Plautz

29

자바 스크립트에서 문자열은 변경할 수 없으므로 다음과 같은 작업을 수행해야합니다

var x = "Hello world"
x = x.substring(0, i) + 'h' + x.substring(i+1);

i에서 x의 문자를 'h'로 바꾸려면


28
str = str.split('');
str[3] = 'h';
str = str.join('');

4
명확하고 간단하지만 현재 사용하는 경우 (예 : 😀 등) 이모티콘 작동하지 않습니다 splitjoin
녹색

1
es6에서는 Array.from (str)이 더 나은 옵션이라고 생각하지만, 그 지식을 가지고 여기에서 간결하게 무언가를 배웠으므로 감사합니다!
David Kamer 2016 년

7

콜백과 함께 String.replace를 사용하는 1 줄 라이너

// 0 - index to replace, 'f' - replacement string
'dog'.replace(/./g, (c, i) => i == 0? 'f': c)
// "fog"

설명 :

//String.replace will call the callback on each pattern match
//in this case - each character
'dog'.replace(/./g, function (character, index) {
   if (index == 0) //we want to replace the first character
     return 'f'
   return character //leaving other characters the same
})

6

이 방법은 작은 길이의 문자열에는 좋지만 큰 텍스트에는 느릴 수 있습니다.

var x = "White Dog";
var arr = x.split(""); // ["W", "h", "i", "t", "e", " ", "D", "o", "g"]
arr.splice(6, 1, 'F');
var result = arr.join(""); // "White Fog"

/* 
  Here 6 is starting index and 1 is no. of array elements to remove and 
  final argument 'F' is the new character to be inserted. 
*/

3

@CemKalyoncu : 큰 답변 감사합니다!

또한 Array.splice 메서드와 비슷하게 만들기 위해 약간 조정했습니다 (@Ates의 메모를 고려했습니다).

spliceString=function(string, index, numToDelete, char) {
      return string.substr(0, index) + char + string.substr(index+numToDelete);
   }

var myString="hello world!";
spliceString(myString,myString.lastIndexOf('l'),2,'mhole'); // "hello wormhole!"

왜 이것이 투표에 실패했는지 잘 모르겠습니다. 합법적 인 답변입니다. 표시된대로 작동합니다. 그리고 Array.splice유형 기능 과 일치 합니다.
Scrimothy

3

이것은 다음과 유사하게 작동합니다 Array.splice.

String.prototype.splice = function (i, j, str) {
    return this.substr(0, i) + str + this.substr(j, this.length);
};

3

당신은 시도 할 수 있습니다

var strArr = str.split("");

strArr[0] = 'h';

str = strArr.join("");

2

문자열의 문자를 바꾸려면 변경 가능한 문자열을 만들어야합니다. 이것들은 본질적으로 문자 배열입니다. 팩토리를 만들 수 있습니다 :

  function MutableString(str) {
    var result = str.split("");
    result.toString = function() {
      return this.join("");
    }
    return result;
  }

그런 다음 문자에 액세스 할 수 있으며 문자열로 사용될 때 전체 배열이 문자열로 변환됩니다.

  var x = MutableString("Hello");
  x[0] = "B"; // yes, we can alter the character
  x.push("!"); // good performance: no new string is created
  var y = "Hi, "+x; // converted to string: "Hi, Bello!"

2

Afanasii Kurakin의 답변을 요약하면 다음과 같습니다.

function replaceAt(str, index, ch) {
    return str.replace(/./g, (c, i) => i == index ? ch : c)
}

let str = 'Hello World'
str = replaceAt(str, 1, 'u')
console.log(str) // Hullo World

정규 표현식과 replacer 함수를 모두 확장하고 설명해 보겠습니다.

function replaceAt(str, index, newChar) {
    function replacer(origChar, strIndex) {
        if (strIndex === index)
            return newChar
        else
            return origChar
    }
    return str.replace(/./g, replacer)
}

let str = 'Hello World'
str = replaceAt(str, 1, 'u')
console.log(str) // Hullo World

정규식 .은 정확히 하나의 문자와 일치합니다. 는 g이 for 루프의 모든 문자와 일치합니다. replacer기능은 오리지널 캐릭터와 그 캐릭터가 문자열에있는 경우의 인덱스를 모두 제공이라고합니다. 우리는 간단한 메이크업 if문은 우리가 반환하는거야 있는지 확인하거나 origChar또는newChar .


2

inset 메소드를 포함하도록 문자열 유형을 확장 할 수 있습니다.

String.prototype.append = function (index,value) {
  return this.slice(0,index) + value + this.slice(index);
};

var s = "New string";
alert(s.append(4,"complete "));

그런 다음 함수를 호출 할 수 있습니다.


1

나는 당신이 묻는 것과 비슷한 기능을 수행했습니다. 문자열의 문자가 허용되지 않는 문자의 배열에 있는지 확인합니다.

    var validate = function(value){
        var notAllowed = [";","_",">","<","'","%","$","&","/","|",":","=","*"];
        for(var i=0; i<value.length; i++){
            if(notAllowed.indexOf(value.charAt(i)) > -1){
               value = value.replace(value.charAt(i), "");
               value = validate(value);
            }
       }
      return value;
   }

1

이것은 RegExp로 쉽게 달성 할 수 있습니다!

const str = 'Hello RegEx!';
const index = 11;
const replaceWith = 'p';

//'Hello RegEx!'.replace(/^(.{11})(.)/, `$1p`);
str.replace(new RegExp(`^(.{${ index }})(.)`), `$1${ replaceWith }`);

//< "Hello RegExp"

1

다음은 반응 / 자바 스크립트의 색인에서 단어 또는 개별 문자의 스타일을 지정하려는 경우에 나온 버전입니다.

replaceAt( yourArrayOfIndexes, yourString/orArrayOfStrings ) 

실제 예 : https://codesandbox.io/s/ov7zxp9mjq

function replaceAt(indexArray, [...string]) {
    const replaceValue = i => string[i] = <b>{string[i]}</b>;
    indexArray.forEach(replaceValue);
    return string;
}

그리고 다른 대안이 있습니다.

function replaceAt(indexArray, [...string]) {
    const startTag = '<b>';
    const endTag = '</b>';
    const tagLetter = i => string.splice(i, 1, startTag + string[i] + endTag);
    indexArray.forEach(tagLetter);
    return string.join('');
}

그리고 또 다른...

function replaceAt(indexArray, [...string]) {
    for (let i = 0; i < indexArray.length; i++) {
        string = Object.assign(string, {
          [indexArray[i]]: <b>{string[indexArray[i]]}</b>
        });
    }
    return string;
}

0

나는 이것이 오래되었다는 것을 알고 있지만 솔루션은 음의 인덱스에서 작동하지 않으므로 패치를 추가합니다. 그것이 누군가를 돕기를 바랍니다

String.prototype.replaceAt=function(index, character) {
    if(index>-1) return this.substr(0, index) + character + this.substr(index+character.length);
    else return this.substr(0, this.length+index) + character + this.substr(index+character.length);

}

0

Kth인덱스 (0 기반 인덱스) 를로 바꾸려고한다고 가정하겠습니다 'Z'. 당신 Regex은 이것을 할 수 있습니다 .

var re = var re = new RegExp("((.){" + K + "})((.){1})")
str.replace(re, "$1A$`");

왜이 태그가 유용하지 않습니까?
ksp

이 정규식이 작동하는지 확인하지는 않았지만 아마도 상태 머신 (정규 표현식)을 컴파일하는 것보다 새 문자열을 만드는 것이 훨씬 빠르기 때문에 하향 조정되었을 수 있습니다. 매우 비쌉니다.
Felo Vilches

0

다음 함수를 사용하여 문자열의 특정 위치 를 바꾸 Character거나 String특정 위치에서 사용할 수 있습니다 . 다음의 모든 대소 문자를 교체하려면 String.prototype.replaceAllMatches()function을 사용하십시오 .

String.prototype.replaceMatch = function(matchkey, replaceStr, matchIndex) {
    var retStr = this, repeatedIndex = 0;
    for (var x = 0; (matchkey != null) && (retStr.indexOf(matchkey) > -1); x++) {
        if (repeatedIndex == 0 && x == 0) {
            repeatedIndex = retStr.indexOf(matchkey);
        } else { // matchIndex > 0
            repeatedIndex = retStr.indexOf(matchkey, repeatedIndex + 1);
        }
        if (x == matchIndex) {
            retStr = retStr.substring(0, repeatedIndex) + replaceStr + retStr.substring(repeatedIndex + (matchkey.length));
            matchkey = null; // To break the loop.
        }
    }
    return retStr;
};

테스트:

var str = "yash yas $dfdas.**";

console.log('Index Matched replace : ', str.replaceMatch('as', '*', 2) );
console.log('Index Matched replace : ', str.replaceMatch('y', '~', 1) );

산출:

Index Matched replace :  yash yas $dfd*.**
Index Matched replace :  yash ~as $dfdas.**

-1

다음은 삼항 및 맵 연산자를 사용하는 솔루션입니다. 당신이 나에게 물어 보면, 더 읽기 쉽고, 유지하기 쉬운 끝을 이해하기가 더 쉽습니다.

es6 및 모범 사례에 더 가깝습니다.

function replaceAt() {
  const replaceAt = document.getElementById('replaceAt').value;

  const str = 'ThisIsATestStringToReplaceCharAtSomePosition';
  const newStr = Array.from(str).map((character, charIndex) => charIndex === (replaceAt - 1) ? '' : character).join('');

  console.log(`New string: ${newStr}`);
}
<input type="number" id="replaceAt" min="1" max="44" oninput="replaceAt()"/>


-3

여기의 방법은 복잡합니다. 나는 이렇게 할 것입니다 :

var myString = "this is my string";
myString = myString.replace(myString.charAt(number goes here), "insert replacement here");

이것은 얻는 것처럼 간단합니다.


6
사실 아니다. 실제로 캐릭터의 첫 번째 항목을 대체합니다. 여전히 틀렸다.
Tomáš Zato-복원 Monica Monica
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.