ฉันจะตัดการเริ่มต้นและสิ้นสุดเครื่องหมายคำพูดคู่จากสตริงได้อย่างไร


143

ฉันต้องการตัดการเริ่มต้นและสิ้นสุดเครื่องหมายคำพูดคู่ (") จากสตริง
ฉันจะบรรลุสิ่งนั้นใน Java ได้อย่างไรขอบคุณ!


1
เป็นที่ทราบกันดีว่าสตริงมีเครื่องหมายคำพูดอยู่รอบ ๆ หรือกำลังตรวจสอบคำพูดเป็นส่วนหนึ่งของปัญหา
Michael Myers

คำตอบ:


257

คุณสามารถใช้String#replaceAll()กับรูปแบบ^\"|\"$สำหรับสิ่งนี้

เช่น

string = string.replaceAll("^\"|\"$", "");

ต้องการเรียนรู้เพิ่มเติมเกี่ยวกับการแสดงออกปกติมีอัล OOK ที่http://regular-expression.info

ที่กล่าวมานี้มีกลิ่นคล้ายกับว่าคุณกำลังพยายามประดิษฐ์ตัวแยกวิเคราะห์ CSV ถ้าเป็นเช่นนั้นผมขอแนะนำให้ไปดูรอบ ๆ ห้องสมุดที่มีอยู่เช่นOpenCSV


6
คุณไม่คิดว่ามันจะแทนที่เครื่องหมายคำพูดคู่ที่เกิดขึ้นทั้งหมดด้วยสตริงว่างเปล่าแทนที่จะเป็นครั้งแรกและครั้งสุดท้าย
GuruKulki

1
@ufk: นี่ไม่ใช่ regex ที่ซับซ้อน มิฉะนั้นคุณอาจต้องการที่จะยุ่งยากกับพวงของString#indexOf(), String#substring()วิธีการและอื่น ๆ เร็วขึ้นเพียงเล็กน้อย แต่เป็นโค้ดที่มากกว่า @GK: เอ่อคุณได้อ่าน / เข้าใจ regex หรือไม่หรือแม้แต่ทดสอบมัน?
BalusC

12
@GK เครื่องหมายคาเร็ตแสดงถึงจุดเริ่มต้นของสตริงที่ค้นหาและเครื่องหมายดอลลาร์แสดงถึงจุดสิ้นสุด เครื่องหมายแบ็กสแลชที่นี่ "หลบหนี" คำพูดต่อไปนี้จึงถือว่าเป็นเพียงอักขระ ดังนั้น regex นี้จึงบอกว่าให้แทนที่เครื่องหมายคำพูดที่เกิดขึ้นทั้งหมดในตอนเริ่มต้นหรืออ้างถึงตอนท้ายด้วยสตริงว่าง ตามที่ร้องขอ
Carl Manaster

2
@ มาร์ค: ฉันไม่แน่ใจว่านั่นเป็นปัญหาในการพิจารณาคำถามในรูปแบบปัจจุบันอย่างไร
BalusC

8
นี่คือ regex ที่แยกย่อย: ^\"|\"$. |หมายถึง "หรือ" มันจึงจะตรงกับทั้งหรือ^\" จับคู่จุดเริ่มต้นของสตริงและตรงกับจุดสิ้นสุดของสตริง หมายถึงจับคู่คำพูดที่จุดเริ่มต้นของสตริงและตรงกับคำพูดที่ท้ายสตริง \"$^$^\"\"$
ibizaman

32

หากต้องการลบอักขระตัวแรกและอักขระสุดท้ายออกจากสตริงให้ใช้:

myString = myString.substring(1, myString.length()-1);

18
สิ่งนี้ต้องการให้รับประกันราคาเท่านั้น หากไม่มีการรับประกันคุณจะต้องตรวจสอบก่อนล่วงหน้า
BalusC

4
@BalusC: แน่นอน จากการอ่านคำถามของฉันดูเหมือนว่าสตริงจะมีเครื่องหมายคำพูดอยู่รอบ ๆ
Michael Myers

.length ไม่ใช่คุณสมบัติ
Martin

4
@Martin: .length เป็นคุณสมบัติของอาร์เรย์ แต่. length () เป็นวิธีการของ Strings
Michael Myers

@MichaelMyers: อ๊ะขอโทษที่ฉันอยู่ในโหมดจาวาสคริปต์ ความผิดพลาดของฉัน.
Martin

18

นอกจากนี้กับ Apache StringUtils.strip():

 StringUtils.strip(null, *)          = null
 StringUtils.strip("", *)            = ""
 StringUtils.strip("abc", null)      = "abc"
 StringUtils.strip("  abc", null)    = "abc"
 StringUtils.strip("abc  ", null)    = "abc"
 StringUtils.strip(" abc ", null)    = "abc"
 StringUtils.strip("  abcyx", "xyz") = "  abc"

ดังนั้น,

final String SchrodingersQuotedString = "may or may not be quoted";
StringUtils.strip(SchrodingersQuotedString, "\""); //quoted no more

วิธีนี้ใช้ได้ทั้งกับสตริงที่ยกมาและไม่มีเครื่องหมายคำพูดดังที่แสดงในตัวอย่างของฉัน ข้อเสียเพียงอย่างเดียวคือจะไม่มองหาเครื่องหมายคำพูดที่ตรงกันอย่างเคร่งครัดเฉพาะอักขระเครื่องหมายคำพูดนำหน้าและต่อท้าย (กล่าวคือไม่มีความแตกต่างระหว่างสตริงที่ยกมา"partiallyและ"fully"สตริงที่ยกมา)


14

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

someString.replace (/(^")|("$)/g, '')

2
อาจรวมเครื่องหมายคำพูดเดี่ยวเกินไปแทนที่ (/ (^ \ "| \ ') | (\" | \' $) / g, "");
บ๊อบ

13

หากเครื่องหมายคำพูดคู่มีอยู่ที่จุดเริ่มต้นและจุดสิ้นสุดรหัสง่ายๆเช่นนี้จะทำงานได้อย่างสมบูรณ์:

string = string.replace("\"", "");


12

การใช้ Guava ช่วยให้คุณเขียนได้สวยหรูขึ้น CharMatcher.is('\"').trimFrom(mystring);


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

10

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

if (string.length() >= 2 && string.charAt(0) == '"' && string.charAt(string.length() - 1) == '"')
{
    string = string.substring(1, string.length() - 1);
}

นี่เป็นคำตอบที่มีประสิทธิภาพมากที่สุดตามลำดับความสำคัญและยังระบุถึงสิ่งที่ต้องทำเกี่ยวกับการมีหรือไม่มีเครื่องหมายคำพูด
entonio

7

Kotlin

ใน Kotlin คุณสามารถใช้String.removeSurrounding (ตัวคั่น: CharSequence)

เช่น

string.removeSurrounding("\"")

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

ซอร์สโค้ดมีลักษณะดังนี้:

public fun String.removeSurrounding(delimiter: CharSequence): String = removeSurrounding(delimiter, delimiter)

public fun String.removeSurrounding(prefix: CharSequence, suffix: CharSequence): String {
    if ((length >= prefix.length + suffix.length) && startsWith(prefix) && endsWith(suffix)) {
        return substring(prefix.length, length - suffix.length)
    }
    return this
}

1
มีภาษาโปรแกรมอื่น ๆ อีกหลายร้อยภาษา ทำไมคุณถึงให้คำตอบสำหรับ Kotlin และไม่ใช่สำหรับคนอื่น :-)
nickolay.laptev

3
คำถามดีๆ @ nickolay.laptev! :) ฉันเคยเขียน java และฉันได้ย้ายไปที่ kotlin และเนื่องจากฉันเป็นนักพัฒนา Android ฉันคิดว่าอาจมีนักพัฒนาคนอื่นอยู่ในตำแหน่งเดียวกันดังนั้นสิ่งนี้จึงเป็นประโยชน์สำหรับพวกเขาเช่นกัน นอกจากนี้removeSurrounding()วิธีการที่ฉันแบ่งปันข้างต้นยังช่วยให้ฉันเข้าใจได้ง่ายโดยนักพัฒนา java ทุกคน
Ryan Amaral

1
คำตอบเดียวนี้แสดงให้เห็นถึงจุดรวมของการนำ Kotlin มาใช้ใน Java codebase ที่คุณมีอยู่!
Kirill Groshkov

3

เมื่อใช้กับรูปแบบด้านล่างjava.util.regex.Matcherจะจับคู่สตริงใดก็ได้ระหว่างเครื่องหมายคำพูดคู่โดยไม่มีผลต่อการเกิดขึ้นของเครื่องหมายคำพูดคู่ภายในสตริง:

"[^\"][\\p{Print}]*[^\"]"

2

ในการลบเครื่องหมายคำพูดคู่อย่างน้อยหนึ่งรายการออกจากจุดเริ่มต้นและจุดสิ้นสุดของสตริงใน Java คุณต้องใช้โซลูชันที่ใช้ regex:

String result = input_str.replaceAll("^\"+|\"+$", "");

หากคุณต้องการลบเครื่องหมายคำพูดเดี่ยว:

String result = input_str.replaceAll("^[\"']+|[\"']+$", "");

หมายเหตุ : หากสตริงของคุณมี"อยู่ข้างในวิธีนี้อาจทำให้เกิดปัญหา (เช่น"Name": "John"=> Name": "John)

ดูการสาธิต Java ที่นี่ :

String input_str = "\"'some string'\"";
String result = input_str.replaceAll("^[\"']+|[\"']+$", "");
System.out.println(result); // => some string

2

แก้ไขคำตอบของ @ brcolow เล็กน้อย

if (string != null && string.length() >= 2 && string.startsWith("\"") && string.endsWith("\"") {
    string = string.substring(1, string.length() - 1);
}

ฉันคิดว่าอาร์กิวเมนต์เมธอดควรใส่คำอธิบายประกอบ@NonNullและมันน่าจะมีอะไรบางอย่างObjects.requireNonNull(string)อยู่ข้างในเพราะถ้ามีคนเรียก stripQuotes (null) พวกเขาอาจทำเช่นนั้นโดยไม่ได้ตั้งใจ!
brcolow

2

แก้ไข: เพิ่งตระหนักว่าฉันควรระบุว่าสิ่งนี้ใช้ได้เฉพาะเมื่อมีทั้งสองอย่าง มิฉะนั้นจะไม่ถือว่าสตริงถูกยกมา สถานการณ์ดังกล่าวปรากฏให้ฉันเห็นเมื่อทำงานกับไฟล์ CSV

org.apache.commons.lang3.StringUtils.unwrap("\"abc\"", "\"")    = "abc"
org.apache.commons.lang3.StringUtils.unwrap("\"abc", "\"")    = "\"abc"
org.apache.commons.lang3.StringUtils.unwrap("abc\"", "\"")    = "abc\""


1
private static String removeQuotesFromStartAndEndOfString(String inputStr) {
    String result = inputStr;
    int firstQuote = inputStr.indexOf('\"');
    int lastQuote = result.lastIndexOf('\"');
    int strLength = inputStr.length();
    if (firstQuote == 0 && lastQuote == strLength - 1) {
        result = result.substring(1, strLength - 1);
    }
    return result;
}

1

สกาล่า

s.stripPrefix("\"").stripSuffix("\"")

สิ่งนี้ใช้ได้ไม่ว่าสตริงจะมีหรือไม่มีเครื่องหมายคำพูดตอนเริ่มต้นและ / หรือสิ้นสุด

แก้ไข: ขออภัย Scala เท่านั้น


1

ฉันกำลังใช้บางสิ่งที่เรียบง่ายเช่นนี้:

if(str.startsWith("\"") && str.endsWith("\""))
        {
            str = str.substring(1, str.length()-1);
        }

0

ค้นหาดัชนีของแต่ละอัญประกาศและแทรกสตริงว่างที่นั่น


ดังนั้นจึงควรเป็นดัชนีแรกและดัชนีสุดท้ายของ qoute คู่
GuruKulki

0
public String removeDoubleQuotes(String request) {
    return request.replace("\"", "");
}

3
คำถามนี้มีคำตอบหลายคำตอบและคำตอบที่ยอมรับแล้ว คุณช่วยอธิบายได้ไหมว่า (โดยแก้ไขคำตอบ) คำตอบของคุณแตกต่างจากคำตอบอื่น ๆ อย่างไร นอกจากนี้โปรดทราบว่าคำตอบแบบใช้รหัสเท่านั้นไม่มีประโยชน์ในระยะยาว
7uc1f3r

3
สิ่งนี้ได้แนะนำไปแล้วในคำตอบนี้stackoverflow.com/a/25452078/1839439โปรดอย่าเพิ่มอันอื่น
Dharman

ฉันกำลังการออกเสียงลงคะแนนในการลบคำตอบนี้เพราะมันคือการทำสำเนาในองค์ประกอบที่สำคัญของstackoverflow.com/a/25452078/1839439 นอกจากนี้ยังมีคำตอบที่ถูกลบอื่น ๆ สำหรับการโพสต์คำตอบนี้ใหม่ ตามคำตอบที่ซ้ำกันของแฟล็กในคำถามเดียวกันไม่มีค่าเพิ่มเติมสำหรับ SO ที่จะเก็บคำตอบสองคำไว้ด้วยโซลูชันเดียวกัน จากรีวิว .
Trenton McKinney
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.