JavaScript สับ / แบ่ง / ตัดอักขระตัวสุดท้ายในสตริง


1973

ฉันมีสตริงและฉันต้องการมันกลับมา12345.0012345.0

ฉันได้ดูtrimแล้ว แต่ดูเหมือนว่ามันเป็นเพียงการตัดช่องว่างและsliceที่ฉันไม่เห็นว่าสิ่งนี้จะทำงาน ข้อเสนอแนะใด ๆ


36
คุณสนใจที่จะปัดเศษหรือไม่? 12345.46 = 12345.5 หรือ 12345.4?
RSolberg

9
คุณรู้หรือไม่ว่าคำต่อท้ายคืออะไรหรือคุณต้องการแยกและลบคำสุดท้ายตามขีดล่าง
Cᴏʀʏ

65
Ho ho ho, @RSolberg: คุณไม่สามารถปัดเชือก!
Ziggy

50
@Ziggy พูดว่าอะไรนะ? Math.round('0.5') === 1;)
TWiStErRob

16
@TWiStErRob โอ้ JavaScript ฉันจะทำอะไรกับคุณ * shakes head *
Chuck Le Butt

คำตอบ:


3211

คุณสามารถใช้ฟังก์ชั่นย่อย :

let str = "12345.00";
str = str.substring(0, str.length - 1);
console.log(str);

นี่คือคำตอบที่ได้รับการยอมรับ แต่ตามบทสนทนาด้านล่างไวยากรณ์ของส่วนแบ่งจะชัดเจนกว่ามาก:

let str = "12345.00";
str = str.slice(0, -1); 
console.log(str);


23
@Kuu - สัญกรณ์ชิ้นสะอาดกว่าสำหรับฉันมาก ก่อนหน้านี้ฉันใช้เวอร์ชันย่อย ขอบคุณ!
Matt Ball

32
ยกโทษให้ฉันถ้าฉันผิด แต่คุณไม่จำเป็นต้องกำหนดค่าของ str.substring ให้ str อีกครั้งหรือไม่ ไลค์str = str.substring(0, str.length -1);
Doug Molineux

10
sliceและsubstringวิธีการทั้งหมดที่มากที่สุดเดียวกัน; ยกเว้นว่าการslice()ยอมรับดัชนีเชิงลบสัมพันธ์กับจุดสิ้นสุดของสตริง แต่ไม่ใช่substringมันจะพ่นout-of-boundข้อผิดพลาด
Amol M Kulkarni

20
ในกรณีที่ใครสงสัยsubstringเป็น 11% sliceเร็วกว่า jsperf.com/js-slice-vs-substring-test
BenR

19
ซับสตริงคือการเพิ่มประสิทธิภาพแบบไมโครบ้าซึ่งฉันไม่คิดว่าคุณควรทำ สูงสุดเพื่อให้สามารถอ่านได้ก่อน จากนั้นปรับผลไม้ที่แขวนต่ำให้เหมาะสมหากต้องการ
อัลเฟรด

1306

คุณสามารถใช้ชิ้น ! คุณเพียงแค่ต้องทำให้แน่ใจว่าคุณรู้วิธีใช้งาน ค่าบวก # เป็นค่าสัมพัทธ์กับจุดเริ่มต้นตัวเลขลบจะสัมพันธ์กับจุดสิ้นสุด

js>"12345.00".slice(0,-1)
12345.0

75
เมื่อเปรียบเทียบกับโซลูชันที่ยอมรับแล้วนี่เป็นวิธีที่ยอดเยี่ยมกว่าและสามารถใช้ได้แม้กับสตริงที่สร้างขึ้นแบบไดนามิก
Sameer Alibhai

1
ฉันชอบวิธีนี้เพราะมันทำให้ jives กับ php ที่คิดฟังก์ชั่น substr ง่ายต่อการจดจำและเขียนได้ทันที
ผู้เบิกทาง

2
@SameerAlibhai ฉันเห็นด้วยกับคุณ แต่ไม่สามารถใช้substringวิธีนี้กับสตริงแบบไดนามิกได้หรือไม่ โดยใช้ str.length เพื่อรับความยาวแบบไดนามิกหรือไม่
Doug Molineux

ควรเพิ่มว่าดัชนีแรกนั้นครอบคลุมและมีเอกสิทธิ์ที่สอง
ธรรมดา

@KevinBeal คุณสามารถใช้ F12 ในเบราว์เซอร์กระแสหลักและป้อนลงในคอนโซลทำงานบนหน้าใดก็ได้และคุณยังมีบริบทและสามารถโหลดไลบรารีได้
TWiStErRob

263

คุณสามารถใช้วิธีการสตริงย่อยของวัตถุสตริง JavaScript:

s = s.substring(0, s.length - 4)

sมันไม่มีเงื่อนไขเอาช่วงสี่ตัวละครจากสตริง

อย่างไรก็ตามหากคุณต้องการลบอักขระสี่ตัวสุดท้ายแบบมีเงื่อนไขเฉพาะในกรณีที่เป็นอย่างแน่นอน _bar :

var re = /_bar$/;
s.replace(re, "");

107
sliceดีกว่าที่นี่ s.slice(0, -4)
Tim Down

12
อีกวิธีหนึ่ง: s.slice (0, - "_ bar" .length) (มีประโยชน์หากไม่ต้องการ hardcode จำนวนอักขระ)
Mahn

3
ฉันชอบอันนี้เพราะเขายังให้ความช่วยเหลือในการแทนที่ตอนจบที่ระบุ
Mike Graf

162

วิธีที่ง่ายที่สุดคือการใช้sliceวิธีการของสตริงซึ่งช่วยให้ตำแหน่งเชิงลบ (สอดคล้องกับ offsets จากจุดสิ้นสุดของสตริง):

const s = "your string";
const withoutLastFourChars = s.slice(0, -4);

หากคุณต้องการอะไรที่กว้างกว่านี้เพื่อลบทุกอย่างหลังจาก (และรวมถึงขีดล่างสุดท้าย) คุณสามารถทำสิ่งต่อไปนี้ (ตราบใดที่sรับประกันว่ามีขีดล่างอย่างน้อยหนึ่งอัน):

const s = "your_string";
const withoutLastChunk = s.slice(0, s.lastIndexOf("_"));
console.log(withoutLastChunk);


67

สำหรับตัวอย่างของคุณฉันขอแนะนำให้ทำเช่นนี้substring:

console.log(parseFloat('12345.00').toFixed(1));

โปรดทราบว่านี่จะเป็นการปัดเศษตัวเลขซึ่งฉันคิดว่าเป็นที่ต้องการ แต่อาจจะไม่:

console.log(parseFloat('12345.46').toFixed(1));


11
+1 นี่คือสิ่งที่ OP ต้องการลืมข้อสันนิษฐานที่ผิดว่ามีสายที่จะตัดแต่ง
naugtur

2
มันไม่ใช่สมมติฐานที่ผิด ๆ OP พูดถึงสตริง คุณเป็นสมมติฐานที่ผิดเนื่องจาก OP ไม่ได้พูดถึงการปัดเศษตัวเลข
Fernando

30

การใช้ฟังก์ชั่นการแบ่งส่วนของ JavaScript:

let string = 'foo_bar';
string = string.slice(0, -4); // Slice off last four characters here
console.log(string);

สามารถใช้เพื่อลบ '_bar' ที่ส่วนท้ายของสตริงได้ทุกความยาว


19

นิพจน์ทั่วไปคือสิ่งที่คุณกำลังมองหา:

let str = "foo_bar";
console.log(str.replace(/_bar$/, ""));


โซลูชันของคุณใช้งานได้ แต่คำตอบของอเล็กซ์นั้นมีความครอบคลุมมากกว่า ดังนั้นฉันจะยอมรับเขา ขอบคุณ!
อัลเบิร์ต

1
วิธีนี้ช่วยแก้ปัญหาที่เกี่ยวข้องกับการลบแบบมีเงื่อนไขแทนที่จะตัดทอนแบบสุ่มสี่สุ่มห้า
Aaron




7
  1. (. *) จับภาพตัวละครหลาย ๆ ครั้ง

console.log("a string".match(/(.*).$/)[1]);

  1. ., ตรงกับอักขระตัวสุดท้ายในกรณีนี้

console.log("a string".match(/(.*).$/));

  1. $ ตรงกับจุดสิ้นสุดของสตริง

console.log("a string".match(/(.*).{2}$/)[1]);


9
ฉันชอบสิ่งนี้เพราะแม้. splice () คุณพบวิธีที่จะใช้การแสดงออกปกติ
QueueHammer

นอกเหนือจากการไม่รับ Unicode แล้วยังไม่ตรงกับตัวแบ่งบรรทัด
user4642212


5

นี่คือทางเลือกที่ฉันไม่คิดว่าฉันได้เห็นในคำตอบอื่น ๆ เพื่อความสนุกสนาน

var strArr = "hello i'm a string".split("");
strArr.pop();
document.write(strArr.join(""));

ไม่เป็นที่เข้าใจง่ายหรือง่ายเหมือนฝางหรือซับสตริง แต่จะช่วยให้คุณเล่นกับสตริงโดยใช้วิธีอาร์เรย์ที่ดีดังนั้นควรรู้


4
debris = string.split("_") //explode string into array of strings indexed by "_"

debris.pop(); //pop last element off the array (which you didn't want)

result = debris.join("_"); //fuse the remainng items together like the sun


3

หากคุณต้องการปัดเศษทั่วไปให้ลอยแทนที่จะเป็นการตัดแต่งอักขระตัวสุดท้าย:

var float1 = 12345.00,
    float2 = 12345.4567,
    float3 = 12345.982;

var MoreMath = {
    /**
     * Rounds a value to the specified number of decimals
     * @param float value The value to be rounded
     * @param int nrDecimals The number of decimals to round value to
     * @return float value rounded to nrDecimals decimals
     */
    round: function (value, nrDecimals) {
        var x = nrDecimals > 0 ? 10 * parseInt(nrDecimals, 10) : 1;
        return Math.round(value * x) / x;
    }
}

MoreMath.round(float1, 1) => 12345.0
MoreMath.round(float2, 1) => 12345.5
MoreMath.round(float3, 1) => 12346.0

แก้ไข:ดูเหมือนว่ามีฟังก์ชั่นในตัวสำหรับเรื่องนี้ตามที่เปาโลชี้ให้เห็น ทางออกนั้นชัดเจนกว่าของฉันมาก ใช้parseFloatตามด้วยtoFixed




1

ประสิทธิภาพ

วันนี้ 2020.05.13 ฉันทำการทดสอบโซลูชันที่เลือกใน Chrome v81.0, Safari v13.1 และ Firefox v76.0 บน MacOs High Sierra v10.13.6

สรุปผลการวิจัย

  • slice(0,-1)(D) เป็นไปอย่างรวดเร็วหรือวิธีที่เร็วที่สุดสำหรับสตริงสั้นและระยะยาวและขอแนะนำเป็นวิธีแก้ปัญหาเบราว์เซอร์ได้อย่างรวดเร็ว
  • โซลูชั่นบนพื้นฐานของ substring (C) และsubstr(E) นั้นรวดเร็ว
  • โซลูชันที่ใช้นิพจน์ทั่วไป (A, B) นั้นช้า / ปานกลางอย่างรวดเร็ว
  • โซลูชัน B, F และ G ช้าสำหรับสายยาว
  • โซลูชัน F ช้าที่สุดสำหรับสตริงสั้น ๆ G ช้าที่สุดสำหรับสตริงยาว

ป้อนคำอธิบายรูปภาพที่นี่

รายละเอียด

ฉันทำการทดสอบสองครั้งเพื่อหาโซลูชันA , B , C , D , E ( ต่อ ), F , G (ของฉัน)

  • สำหรับสตริงสั้น 8-char (จากคำถาม OP) - คุณสามารถเรียกใช้ นี่
  • สำหรับสตริงยาว 1M - คุณสามารถเรียกใช้ที่นี่

วิธีแก้ไขมีการนำเสนอในตัวอย่างด้านล่าง

นี่คือตัวอย่างผลลัพธ์สำหรับ Chrome สำหรับสตริงสั้น ๆ

ป้อนคำอธิบายรูปภาพที่นี่


1

ระวังว่าString.prototype.{ split, slice, substr, substring }ใช้งานกับสตริงที่เข้ารหัส UTF-16

ไม่มีคำตอบก่อนหน้านี้ที่ไม่รู้จัก Unicode สตริงจะถูกเข้ารหัสเป็น UTF-16 ในเอนจิ้น JavaScript สมัยใหม่ส่วนใหญ่ แต่จุดโค้ด Unicode ที่สูงกว่านั้นจำเป็นต้องใช้คู่ตัวแทนแทนดังนั้นวิธีสตริงเก่าที่มีอยู่ก่อนหน้านี้จึงใช้งานได้กับหน่วยโค้ด UTF-16 ไม่ใช่จุดโค้ด Unicode

const string = "ẞ🦊";

console.log(string.slice(0, -1)); // "ẞ\ud83e"
console.log(string.substr(0, string.length - 1)); // "ẞ\ud83e"
console.log(string.substring(0, string.length - 1)); // "ẞ\ud83e"
console.log(string.replace(/.$/, "")); // "ẞ\ud83e"
console.log(string.match(/(.*).$/)[1]); // "ẞ\ud83e"

const utf16Chars = string.split("");

utf16Chars.pop();
console.log(utf16Chars.join("")); // "ẞ\ud83e"

นอกจากนี้คำตอบ RegExp ไม่ตรงกับตัวแบ่งบรรทัดที่ท้ายในรูปแบบปัจจุบัน:

const string = "Hello, world!\n";

console.log(string.replace(/.$/, "").endsWith("\n")); // true
console.log(string.match(/(.*).$/) === null); // true


ใช้ตัววนซ้ำสตริงเพื่อวนอักขระ

รหัสที่รับรู้ Unicode ใช้ตัววนซ้ำของสตริง ดูArray.fromและการแพร่กระจาย ... string[Symbol.iterator]สามารถใช้ (เช่นแทนstring ) ได้เช่นกัน

ยังเห็นวิธีการแยกสายอักขระ Unicode กับตัวละครใน JavaScript

ตัวอย่าง:

const string = "ẞ🦊";

console.log(Array.from(string).slice(0, -1).join("")); // "ẞ"
console.log([
  ...string
].slice(0, -1).join("")); // "ẞ"

ใช้sและuธงบนRegExp

dotAllหรือsธงที่ทำให้.ตัวละครแบ่งบรรทัดตรงกับที่unicodeหรือuธงช่วยให้คุณสมบัติ Unicode บางอย่างเกี่ยวกับ

ตัวอย่าง:

const unicodeString = "ẞ🦊",
  lineBreakString = "Hello, world!\n";

console.log(lineBreakString.replace(/.$/s, "").endsWith("\n")); // false
console.log(lineBreakString.match(/(.*).$/s) === null); // false
console.log(unicodeString.replace(/.$/su, "")); // ẞ
console.log(unicodeString.match(/(.*).$/su)[1]); // ẞ

// Now `split` can be made Unicode-aware:

const unicodeCharacterArray = unicodeString.split(/(?:)/su),
  lineBreakCharacterArray = lineBreakString.split(/(?:)/su);

unicodeCharacterArray.pop();
lineBreakCharacterArray.pop();
console.log(unicodeCharacterArray.join("")); // "ẞ"
console.log(lineBreakCharacterArray.join("").endsWith("\n")); // false


โปรดทราบว่าบางส่วนของกราฟประกอบด้วยจุดโค้ดมากกว่าหนึ่งจุดเช่น🏳️‍🌈ซึ่งประกอบด้วยลำดับ🏳(U + 1F3F3), VS16(U + FE0F) , ZWJ(U + 200D) , 🌈(U + 1F308) ที่นี่แม้Array.fromจะแยกสิ่งนี้ออกเป็น "ตัวละคร" สี่ตัว จับคู่เหล่านั้นเป็นไปได้ด้วยUnicode คุณสมบัติหนีข้อเสนอคุณสมบัติลำดับ


-1

ในกรณีที่คุณต้องการลบสิ่งที่อยู่ใกล้กับจุดสิ้นสุดของสตริง (ในกรณีของสตริงขนาดตัวแปร) คุณสามารถรวม slice () และ substr ()

ฉันมีสตริงที่มีมาร์กอัปสร้างขึ้นแบบไดนามิกโดยมีรายการของแท็กสมอคั่นด้วยเครื่องหมายจุลภาค สตริงเป็นสิ่งที่ชอบ:

var str = "<a>text 1,</a><a>text 2,</a><a>text 2.3,</a><a>text abc,</a>";

หากต้องการลบเครื่องหมายจุลภาคสุดท้ายฉันได้ทำสิ่งต่อไปนี้:

str = str.slice(0, -5) + str.substr(-4);

-3

ลองสิ่งนี้:

<script>
    var x="foo_foo_foo_bar";
    for (var i=0; i<=x.length; i++) {
        if (x[i]=="_" && x[i+1]=="b") {
            break;
        }
        else {
            document.write(x[i]);
        }
    }
</script>

นอกจากนี้คุณยังสามารถลองตัวอย่างการทำงานอยู่บนhttp://jsfiddle.net/informativejavascript/F7WTn/87/


3
ขอบคุณ kamal อย่างไรก็ตามฉันได้ทำเครื่องหมายคำตอบข้างต้นว่าเป็นที่ยอมรับสำหรับความต้องการของฉัน สังเกตเครื่องหมายสีเขียวด้านบน แม้ว่าฉันตรวจสอบรหัสของคุณแล้ว :) ตอนนี้ในสถานการณ์ของฉันฉันรู้แค่ลำดับตัวละครทั่วไป มันจะเป็นการดีกว่าถ้าคุณเริ่มตรวจสอบจากจุดสิ้นสุดของสตริง ข้อเสนอแนะของคุณจะล้มเหลวหากฉันมีสตริงที่ดูเหมือน "foo_b_bar" และฉันอยากจะเอา "_bar" สุดท้ายออกไปเท่านั้น ขอบคุณนะ! เป็นประสบการณ์ที่น่าสนใจทีเดียวที่จะถามคำถามเมื่อ 2 ปีก่อนและยังคงได้รับคำตอบในวันนี้ :)
อัลเบิร์ต

-4

@Jason S:

คุณสามารถใช้ชิ้น! คุณเพียงแค่ต้องทำให้แน่ใจว่าคุณรู้วิธีใช้งาน ค่าบวก # เป็นค่าสัมพัทธ์กับจุดเริ่มต้นตัวเลขลบจะสัมพันธ์กับจุดสิ้นสุด

js> "12345.00" .slice (0, -1) 12345.0

ขออภัยสำหรับ graphomany ของฉัน แต่โพสต์ถูกติดแท็ก 'jquery' ก่อนหน้านี้ ดังนั้นคุณไม่สามารถใช้ slice ()ภายใน jQuery ได้เพราะslice ()เป็นวิธี jQuery สำหรับการดำเนินการกับองค์ประกอบ DOM ไม่ใช่ substrings ... อีกนัยหนึ่งคำตอบ@Jon Ericksonแนะนำทางออกที่สมบูรณ์แบบจริงๆ

อย่างไรก็ตามวิธีการของคุณจะทำงานได้จากฟังก์ชั่น jQuery ใน Javascript ธรรมดา จำเป็นต้องพูดเนื่องจากการอภิปรายครั้งล่าสุดในความคิดเห็น jQuery นั้นบ่อยครั้งที่ส่วนขยายของ JS ที่ทดแทนได้บ่อยกว่า ECMAScript ซึ่งเป็นที่รู้จักมากที่สุดของพ่อแม่

ที่นี่ยังมีอยู่สองวิธี:

เป็นของเรา:

string.substring(from,to) เป็นบวกถ้าดัชนี 'เป็น' เป็นโมฆะส่งกลับส่วนที่เหลือของสตริง ดังนั้น: string.substring(from) บวกหรือลบ ...

และอื่น ๆ - substr () - ซึ่งมีช่วงของสตริงย่อยและ 'ความยาว' สามารถบวกได้เท่านั้น: string.substr(start,length)

ผู้ดูแลบางคนแนะนำว่าวิธีสุดท้ายstring.substr(start,length)ไม่ทำงานหรือทำงานผิดพลาดสำหรับ MSIE


3
คุณหมายถึงอะไร String.prototype.sliceเป็นวิธีการพื้นเมือง
naugtur

แค่สิ่งที่คุณพูด วิธีการ Javascript พื้นเมือง แต่ยัง jQuery slice()วิธีการสำหรับการจัดการ DOM: jQuery API: .slice () และแน่ใจได้ว่าสามารถนำมาคิดเหมือนการถ่ายทอดทางพันธุกรรมของ JS Array.slice () แต่มันเป็นสองวิธีที่แตกต่างกันและฉันคิดว่าต้องแยกมันออกจากกัน ดังนั้นมันจึงเป็นการประมาณความรู้นี้
สวิฟท์

12
ถ้าคุณเรียก.sliceใช้ตัวแปรที่เป็นสตริงมันจะทำในสิ่งที่ OP ต้องการ ไม่สำคัญว่าจะเป็น "inside jQuery" และไม่มีวิธีใดที่จะ "แทรกแซง" ในทางใดทางหนึ่งเว้นแต่คุณจะเขียนทับString.prototypeด้วย jQuery ซึ่งฉันมั่นใจว่าจะป้องกันไม่ให้รหัส javascript ใด ๆ ทำงาน คำตอบของคุณเพิ่งบอกว่าคำตอบอื่น ๆ ไม่ดีและอาร์กิวเมนต์ที่คุณระบุนั้นไม่ถูกต้อง
naugtur

1
ฉันเห็นด้วยกับ @naugtur คำตอบนี้ผิดวิธีการแบ่งสตริงของ jQuery ไม่ได้รับผลกระทบ
reconbot

1
ฉันคิดว่าจุด naugtur กำลังทำอยู่นั่นเป็นไปได้ว่าคุณสามารถจบลงด้วยสตริงที่ห่อด้วยวัตถุ jQuery (เช่นถ้าคุณทำการ.dataยักย้ายถ่ายเทที่แฟนซีและจบลงด้วย "สตริง") ซึ่งถ้าคุณเรียกsliceมัน จะไม่ทำในสิ่งที่คุณต้องการ ที่กล่าวว่านี่ไม่ใช่คำตอบที่เป็นประโยชน์จริงๆ
mAAdhaTTah

-8

ใช้สตริงย่อยเพื่อรับทุกอย่างทางด้านซ้ายของ _bar แต่ก่อนอื่นคุณจะต้องได้คำแนะนำของ _bar ในสตริง:

str.substring(3, 7);

3 คือจุดเริ่มต้นและ 7 คือความยาว


1
สิ่งนี้ใช้ได้กับ "foo_bar" ไม่ได้อยู่ใน "foo_foo_bar" คำถามคือเกี่ยวกับสตริงที่มีความยาวใด ๆ แต่เป็นที่สิ้นสุด
ออกแบบโดย Adrian
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.