JavaScriptの特定のインデックスにある文字を置き換えるにはどうすればよいですか?


544

文字列があるとしましょうHello world。インデックス3の文字を置き換える必要があります。インデックスを指定して文字を置き換えるにはどうすればよいですか?

var str = "hello world";

私のようなものが必要です

str.replaceAt(0,"h");

131
奇妙なのは、str[0] = 'x'エラーがスローされないようですが、望ましい効果が得られないことです。
マイケル

6
@Michaelを使用すると、インデックスが0になり、それを「x」に設定すると、そのステートメント自体が新しい値を返します。'バツ'。しかし、すべてが元の内容を変更することはないので、完全に有効です。それは参照ではありません
ポール・シェルテマ

8
@Michael "use strict"がアクティブになっている場合Uncaught TypeError: Cannot assign to read only property '0' of string 'hello world'に実行します:(少なくともWebkitブラウザーでは)
JanTuroň16年

1
JavaScript文字列は不変であり、「その場で」変更できないため、単一の文字を変更することはできません。実際、同じ文字列のすべての出現は1つのオブジェクトです。
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、2009

30
@CemKalyoncu:コードが他のライブラリとうまく動作しない可能性があります。しかし、私はこれまで自分に噛まれたことはありません。
アレックス、

6
@alex:あなたはそれについて正しい、それを行う前にその関数が存在するかどうかを本当にチェックする必要がある。しかし、たとえそうであっても、まったく同じ操作を行う必要があります。
Cem Kalyoncu、2011

80
関数が存在するかどうかを検出しても、後のライブラリが同様の関数を使用/作成する可能性があります-2つの悪いアイデアが悪いものを作ります。一般的に、他の人のコード(コアシステムを含む)をいじらないでください。新しい関数を作成します。
殉教者

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>



単一の文字をそれで置き換えることができるので、私はこの解決策を好みます。1つの文字だけを置き換えたい場合、賛成票が最も多いソリューションは機能しません。2つの文字を置き換えるときにのみ機能します。また、他の多くのコメントで言及されているように、substrはsubstringに置き換える必要があります。
1

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

2
MDNは、String.prototype.substring以上の使用を推奨していますString.prototype.substr
Mikemike

33

ここには多くの答えがあり、それらはすべて2つの方法に基づいています。

  • 方法1:2つの部分文字列を使用して文字列を分割し、その間に文字を挿入します
  • METHOD2:文字列を文字配列に変換し、1つの配列メンバーを置き換えて結合する

個人的には、この2つの方法を異なるケースで使用します。説明させてください。

@FabioPhms:あなたの方法は私が最初に使用した方法であり、多くの文字を含む文字列では悪いと思いました。しかし、問題はたくさんのキャラクターは何ですか?私は10の "lorem ipsum"段落でテストしましたが、数ミリ秒かかりました。次に、10倍の大きな文字列でテストしましたが、実際には大きな違いはありませんでした。うーん。

@ vsync、@ Cory Mawhorter:コメントは明確です。ただし、もう一度、大きな文字列とは何ですか。32 ... 100kbの場合はパフォーマンスが向上し、文字置換のこの1つの操作にはサブストリングバリアントを使用する必要があることに同意します。

しかし、かなりの数の交換が必要になった場合はどうなりますか?

私は自分のテストを実行して、その場合の方が速いことを証明する必要がありました。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(配列変換)の2つのテストがあります。

結果:

  • テスト1:195ms
  • TEST2:6ミリ秒

配列変換はサブストリングを2桁上回るようです!だから-ここで一体何が起こったの???

実際に発生するのは、TEST2のすべての操作がのような代入式を使用して、配列自体に対して行われることstrarr2[p] = nです。割り当ては、大きな文字列の部分文字列と比較して本当に高速であり、それが勝つことは明らかです。

つまり、すべては、その仕事に適したツールを選択することです。再び。


7
テストをjsperfに移動しました。結果は大きく異なります:jsperf.com/string-replace-character。仕事に適したツールを選択することがすべてです;)
colllin '30年

1
@colllin:私は完全に同意します。そのため、ほぼ文字通りjsfiddleからjsperfにテストのクローンを作成しました。ただし、適切なツールを使用する以外に、適切な方法で実行する必要があります。問題に注意してください。アルゴリズムでかなりの数の置換を行わなければならない場合に何が起こるかについて話しています。具体的な例には、10000個の交換品が含まれています。これは、1つのテストに10000回の置換が含まれることを意味します。したがって、jsperfを使用すると、非常に一貫した結果が得られました。jsperf.com / …を参照してください。
OzrenTkalcecKrznaric 2014年

1
これがJavaScriptが嫌いな理由です。このような頻繁で直感的な明らかなユースケースは、プロビジョニングされていません。あなたは人々が文字列内の文字を置き換えたいと思うかもしれない、そして彼らが便利なメソッドを言語に入れることに決めるだろうとそれがjavascriptの作家に起こるだろうと思うでしょう。
ahnbizcad 2015年

1
@colllinはOzrenTkalcecKrznaricとは異なる何かを行いました。OzrenTkalcecKrznaricは、文字列は静的であり、分割は実行前に最適化できると仮定しました。必ずしもそうではありません。実行ごとに分割する必要がある場合、部分文字列のアプローチは小さな文字列で約2〜4倍速く、文字列が大きくなるほど速くなります。私の意見では、これにより、部分文字列がほとんどのユースケースでより適切な実装になり、大きな静的文字列に対する多数の変更が禁止されます。
WiR3D 2016年

3
問題は、test2では、分割と結合がforループの外にあり、単一の文字の置換を複数の置換(不公平)と比較する場合、最初の方法は単一の置換の方が速く、2番目の方法は連鎖置換の場合に次々と優れています
ΘεόφιλοςΜουρατίδης

32

ベクトルの操作は、通常、Stringに連絡するのに最も効果的です。

私は次の機能を提案します:

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

1
多くの文字を変更する必要があり、それが簡単な場合に役立ちます。
Sheepy 2012

6
私はjsperfでテストを作成しました:jsperf.com/replace-character-by-index-Substrはより高速で、32バイトから100 kbまで一貫しています。私はこれに賛成しましたが、私が言うのが難しいほど、これはいい感じですが、どんなサイズの文字列でもsubstrがより良い選択です。
Cory Mawhorter 2013年

これは非常に最適ではありません。
Radko Dinev 2014

これは、小さな文字列を使用することがわかっている場合に適した迅速な解決策です。あなたはプロトタイプを拡張して大丈夫です場合は、2行に類似した動作を実現することができます:Array.prototype.replace = function(index, val) { this[index] = val; return this; }; 'word'.split('').replace(1, '0').join(''); // returns 'w0rd'
マイケルPlautz

29

JavaScriptでは文字列は不変なので、次のようなことをする必要があります

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

xのiの文字を「h」で置き換えるには


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

4
クリアとシンプルですが、現在使用している場合(例えば😀など)絵文字では動作しませんsplitjoin
グリーン

1
es6では、Array.from(str)の方が良いオプションだと思いますが、その知識を持ってここに来て、簡潔なことをあなたから学んだので、ありがとう!
David Kamer

7

コールバックでString.replaceを使用するワンライナー(絵文字サポートなし):

// 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);
};


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

正規表現と置換関数の両方を拡張して説明しましょう。

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

正規表現は.正確に1文字と一致します。これ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

これが、react / javascriptのインデックスで単語または個々の文字のスタイルを設定する場合に思いついたバージョンです。

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、2017

0

次の関数を使用して、文字列の特定の位置を置換Characterまたは変更できますString。以下のすべての一致ケースを置き換えるには、String.prototype.replaceAllMatches()関数を使用します。

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
実際はそうではなくて。実際には、最初に出現する文字を置き換えます。まだ間違っています。
トマーシュZato -復活モニカ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.