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!

ufk
źródło
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 .

BalusC
źródło
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);
Michael Myers
źródło
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).

rath
źródło
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("\"", "");

sunraincyq
źródło
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, '')
Yaniv Levi
źródło
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);

legrass
źródło
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);
}
brcolow
źródło
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
}
Ryan Amaral
źródło
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}]*[^\"]"
Alex F.
źródło
2

Trochę modyfikuję odpowiedź @ brcolow

if (string != null && string.length() >= 2 && string.startsWith("\"") && string.endsWith("\"") {
    string = string.substring(1, string.length() - 1);
}
zmieszany
źródło
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

Brendan Maguire
źródło
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\""
raisercostin
źródło
1
Matcher m = Pattern.compile("^\"(.*)\"$").matcher(value);
String strUnquoted = value;
if (m.find()) {
    strUnquoted = m.group(1);
}
Ravikiran
źródło
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;
}
m0untp
źródło
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
Wiktor Stribiżew
źródło
0

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

GuruKulki
źródło
więc powinien to być pierwszy indeks i ostatni indeks podwójnej qoute.
GuruKulki