Jak mogę wyciąć początek i koniec podwójnego cudzysłowu z ciągu znaków?


139

Chciałbym usunąć początek i koniec podwójnego cudzysłowu (") z ciągu znaków.
Jak mogę to osiągnąć w Javie? Dzięki!


1
Czy już wiadomo, że ciąg zawiera cudzysłowy, czy też sprawdzanie cudzysłowów jest częścią problemu?
Michael Myers

Odpowiedzi:


250

Możesz użyć String#replaceAll()z wzorem^\"|\"$ do tego .

Na przykład

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

Aby dowiedzieć się więcej o wyrażeniach regularnych, wejdź na http://regular-expression.info .

To powiedziawszy, pachnie trochę tak, jakbyś próbował wymyślić parser CSV. Jeśli tak, proponuję rozejrzeć się za istniejącymi bibliotekami, takimi jak OpenCSV .


6
czy nie sądzisz, że zastąpi on wszystkie wystąpienia podwójnych cudzysłowów pustym ciągiem zamiast pierwszego i ostatniego.
GuruKulki

1
@ufk: To nie jest złożone wyrażenie regularne. Można inaczej chcą kłopotów z grupą String#indexOf(), String#substring()metody i tak dalej. Jest tylko odrobinę szybszy, ale zawiera znacznie więcej kodu. @GK: Uh, czy przeczytałeś / zrozumiałeś wyrażenie regularne lub nawet je przetestowałeś?
BalusC

11
@GK daszek reprezentuje początek szukanego ciągu, a znak dolara reprezentuje jego koniec. Odwrotny ukośnik „wymyka” poniższemu cudzysłowie, więc jest traktowany jak tylko znak. Więc to wyrażenie regularne mówi, że wszystkie wystąpienia cudzysłowu na początku lub na końcu należy zastąpić pustym ciągiem. Zgodnie z prośbą.
Carl Manaster

2
@Marc: Nie jestem pewien, jaki to problem, biorąc pod uwagę pytanie w jego obecnej formie.
BalusC

8
Oto regex w podziale: ^\"|\"$. |oznacza „lub”. W ten sposób będzie pasować albo ^\"lub \"$. ^dopasowuje początek ciągu i $koniec ciągu. ^\"oznacza dopasowanie cudzysłowu na początku ciągu i \"$dopasowuje cudzysłów na końcu ciągu.
ibizaman

31

Aby usunąć pierwszy znak i ostatni znak z ciągu, użyj:

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

18
Wymaga to jedynie zagwarantowania obecności cytatów . Jeśli nie ma gwarancji, najpierw musisz to sprawdzić.
BalusC

4
@BalusC: Oczywiście. Po przeczytaniu tego pytania wydaje się, że ciąg znaków jest już otoczony cudzysłowami.
Michael Myers

.length to właściwość, a nie funkcja
Martin

2
@Martin: .length jest właściwością tablic, ale .length () jest metodą ciągów.
Michael Myers

@MichaelMyers: Ups, przepraszam, pracowałem w trybie mentalnym JavaScript. Mój błąd.
Martin

16

Również z 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"

Więc,

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

Ta metoda działa zarówno z ciągami cytowanymi, jak i niecytowanymi, jak pokazano w moim przykładzie. Jedynym minusem jest to, że nie będzie szukał ściśle dopasowanych cudzysłowów, a jedynie początkowe i końcowe znaki cudzysłowu (tj. Brak rozróżnienia między łańcuchami cytowanymi "partiallyi "fully"cytowanymi).


13

Jeśli podwójne cudzysłowy istnieją tylko na początku i na końcu, prosty kod działałby idealnie:

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


13

To najlepszy sposób, jaki znalazłem, na usuwanie podwójnych cudzysłowów z początku i końca ciągu.

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

2
Może uwzględnij także pojedyncze cudzysłowy replace (/ (^ \ "| \ ') | (\" | \' $) / g, "");
bob

11

Używając guawy, możesz pisać bardziej elegancko CharMatcher.is('\"').trimFrom(mystring);


2
czy można przyciąć tylko jeden znak? Na przykład, jeśli mój ciąg kończy się dwoma pojedynczymi cudzysłowami, nadal chcę, aby tylko jeden cudzysłów został przycięty.
vatsal mevada

10

Najpierw sprawdzamy, czy ciąg znaków jest podwójnie cytowany, a jeśli tak, usuwamy go. Możesz pominąć warunek, jeśli w rzeczywistości wiesz, że jest on podwójnie cytowany.

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

Jest to najbardziej skuteczna odpowiedź pod względem wielkości, a nawet określa, co zrobić z opcjonalną lub brakiem kwotowań.
entonio

6

Kotlin

W Kotlinie możesz użyć String.removeSurrounding (delimiter: CharSequence)

Na przykład

string.removeSurrounding("\"")

Usuwa podany ciąg separatora zarówno z początku, jak i końca tego ciągu wtedy i tylko wtedy, gdy zaczyna się od separatora i kończy się nim . W przeciwnym razie zwraca ten ciąg bez zmian.

Kod źródłowy wygląda następująco:

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
}

Istnieją setki innych języków programowania. Dlaczego dałeś odpowiedź dla Kotlina, a nie dla innych :-)?
nickolay.laptev

1
Dobre pytanie @ nickolay.laptev! :) Kiedyś pisałem java i przeniosłem się do kotlina, a ponieważ jestem programistą Androida, pomyślałem, że mogą mieć innych programistów na tym samym stanowisku, więc może to być przydatne dla nich. Ponadto removeSurrounding()metoda, którą udostępniłem powyżej, wydawała mi się łatwa do zrozumienia dla każdego programisty Java.
Ryan Amaral

1
Ta pojedyncza odpowiedź ilustruje cały sens przyjęcia Kotlina w istniejącej bazie kodu Java!
Kirill Groshkov

3

Poniższy wzorzec, użyty z java.util.regex.Matcher, dopasuje dowolny ciąg między podwójnymi cudzysłowami bez wpływu na występowanie podwójnych cudzysłowów w ciągu:

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

2

Trochę modyfikuję odpowiedź @ brcolow

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

Wydaje mi się, że argument metody powinien być opatrzony adnotacją @NonNulli prawdopodobnie powinien mieć w Objects.requireNonNull(string)środku coś podobnego , ponieważ jeśli ktoś wywołuje stripQuotes (null), prawdopodobnie robi to przez pomyłkę!
brcolow

2

Scala

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

Działa to niezależnie od tego, czy ciąg ma cudzysłowy na początku i / lub na końcu, czy nie.

Edycja: Przepraszamy, tylko Scala


2

Edytowano: Właśnie zdałem sobie sprawę, że powinienem określić, że działa to tylko wtedy, gdy oba istnieją. W przeciwnym razie ciąg nie jest cytowany. Taki scenariusz pojawił się u mnie podczas pracy z plikami 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
Matcher m = Pattern.compile("^\"(.*)\"$").matcher(value);
String strUnquoted = value;
if (m.find()) {
    strUnquoted = m.group(1);
}

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

Aby usunąć jeden lub więcej podwójnych cudzysłowów z początku i końca ciągu w Javie, musisz użyć rozwiązania opartego na wyrażeniach regularnych:

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

Jeśli chcesz usunąć również pojedyncze cudzysłowy:

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

UWAGA : Jeśli twój ciąg zawiera "wewnątrz, takie podejście może prowadzić do problemów (np. "Name": "John"=>Name": "John ).

Zobacz demo Java tutaj :

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

0

znajdź indeksy każdego podwójnego cudzysłowu i wstaw tam pusty ciąg.


więc powinien to być pierwszy indeks i ostatni indeks podwójnej qoute.
GuruKulki
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.