Jak usunąć pierwszy i ostatni podwójny cudzysłów?

102

Chcę usunąć podwójne cudzysłowy z:

string = '"" " " ""\\1" " "" ""'

pozyskać:

string = '" " " ""\\1" " "" "'

Starałem się używać rstrip, lstripa strip('[^\"]|[\"$]')ale to nie działa.

W jaki sposób mogę to zrobić?

Walapa
źródło
6
Prawidłowe odpowiedzi podano poniżej. Jeśli chodzi o twoje podejście strip, zwróć uwagę, że a) ta metoda nie przyjmuje wyrażenia regularnego jako argumentu, b) podane wyrażenie regularne i tak nie zadziałałoby ic) ta metoda usuwa wszystkie sąsiadujące znaki, a nie tylko jeden, więc straciłbyś dwa podwójne cudzysłowy z .strip('"').
Tim Pietzcker

Odpowiedzi:

189

Jeśli cytaty, które chcesz usunąć, zawsze będą „pierwszy i ostatni”, jak powiedziałeś, możesz po prostu użyć:

string = string[1:-1]

houbysoft
źródło
Ten poniżej jest bezpieczniejszy!
R Claven,
93

Jeśli nie możesz założyć, że wszystkie przetwarzane ciągi mają podwójne cudzysłowy, możesz użyć czegoś takiego:

if string.startswith('"') and string.endswith('"'):
    string = string[1:-1]

Edytować:

Jestem pewien, że właśnie użyłeś stringtutaj nazwy zmiennej dla przykładu, aw twoim prawdziwym kodzie ma ona użyteczną nazwę, ale czuję się zobowiązany do ostrzeżenia, że ​​istnieje moduł o nazwie stringw standardowych bibliotekach. Nie jest ładowany automatycznie, ale jeśli kiedykolwiek użyjesz, import stringupewnij się, że zmienna go nie przyćmiewa.

tgray
źródło
1
Jeśli ciąg znaków to '"' (tylko jeden podwójny cudzysłów), usunie to pojedynczy znak. Myślę, że prawdopodobnie nie jest to pożądane, prawdopodobnie Walapa chciał usunąć podwójny cudzysłów tylko wtedy, gdy był dopasowany.
dbn
44

Aby usunąć pierwszy i ostatni znak, aw każdym przypadku należy usunąć tylko wtedy, gdy dany znak jest cudzysłowem:

import re

s = re.sub(r'^"|"$', '', s)

Zauważ, że wzorzec RE jest inny niż ten, który podałeś, a operacja polega na sub(„podstawieniu”) z pustym ciągiem zastępczym ( stripjest to metoda łańcuchowa, ale robi coś zupełnie innego niż twoje wymagania, jak wskazywały inne odpowiedzi).

Alex Martelli
źródło
4
Używanie RE tutaj to przesada IMHO. Wolę rozwiązanie z startsWith.
pihentagy
19
Wielu Pythonistów ma podobne reakcje na RE, które są naprawdę nieuzasadnione - RE są dość szybkie. Dodatkowo, rozwiązanie, które „preferujesz”, zgodnie z postem, robi coś zupełnie innego (usuwa pierwszy i ostatni znak tylko wtedy, gdy oba są cudzysłowami - co wydaje się różne od specyfikacji OP) - jeśli początkowe i końcowe cudzysłowy (jeśli są obecne) trzeba usunąć niezależnie, to rozwiązanie staje się blokiem składającym się z 4 zdań i 2 warunków - teraz to przesada w porównaniu z pojedynczym, szybszym wyrażeniem dla tego samego zadania! -)
Alex Martelli
44

WAŻNE: rozszerzam pytanie / odpowiedź, aby usunąć pojedyncze lub podwójne cudzysłowy. I interpretuję to pytanie tak, że oba cytaty muszą być obecne i dopasowane, aby wykonać pasek. W przeciwnym razie ciąg jest zwracany bez zmian.

Aby „usunąć cudzysłowy” reprezentację ciągu, która może zawierać pojedyncze lub podwójne cudzysłowy (jest to rozszerzenie odpowiedzi @ tgray):

def dequote(s):
    """
    If a string has single or double quotes around it, remove them.
    Make sure the pair of quotes match.
    If a matching pair of quotes is not found, return the string unchanged.
    """
    if (s[0] == s[-1]) and s.startswith(("'", '"')):
        return s[1:-1]
    return s

Wyjaśnienie:

startswithmoże wziąć krotkę, aby dopasować dowolną z kilku alternatyw. Powodem DOUBLED nawiasów ((i ))jest to, że przekazujemy JEDEN parametr ("'", '"')do startswith()określenia dozwolonych przedrostków, a nie DWA parametry "'"i '"', które byłyby interpretowane jako przedrostek i (nieprawidłowa) pozycja początkowa.

s[-1] to ostatni znak w ciągu.

Testowanie:

print( dequote("\"he\"l'lo\"") )
print( dequote("'he\"l'lo'") )
print( dequote("he\"l'lo") )
print( dequote("'he\"l'lo\"") )

=>

he"l'lo
he"l'lo
he"l'lo
'he"l'lo"

(Dla mnie wyrażenia regex nie są oczywiste do odczytania, więc nie próbowałem rozszerzać odpowiedzi @ Alex).

ToolmakerSteve
źródło
1
Jeśli najpierw sprawdzisz, czy pierwszy i ostatni znak są takie same, musisz tylko sprawdzić, czy pierwszy znak jest cudzysłowem: def strip_if_quoted (name): if name [0] == name [-1] i name [0 ] in ("'",' "'): nazwa powrotu [1: -1]
TomOnTime
@TomOnTime: Masz rację, to dobra optymalizacja. Zastosowałem to.
ToolmakerSteve
4
Zalecałbym obsługę ciągów o długości maksymalnie 2 znaków. W tej chwili ta funkcja może zgłosić indeks spoza granic dla ciągu o długości 0. Dodatkowo można usunąć cudzysłów z ciągu o długości 1 znaku. Możesz dodać strażnika len(s) >= 2lub coś podobnego.
BrennanR
16

Jeśli ciąg jest zawsze taki, jak pokazujesz:

string[1:-1]
Larry
źródło
9

Prawie skończone. Cytowanie z http://docs.python.org/library/stdtypes.html?highlight=strip#str.strip

Argument chars jest łańcuchem określającym zestaw znaków do usunięcia.

[…]

Argument chars nie jest przedrostkiem ani sufiksem; raczej wszystkie kombinacje jego wartości są usuwane:

Zatem argument nie jest wyrażeniem regularnym.

>>> string = '"" " " ""\\1" " "" ""'
>>> string.strip('"')
' " " ""\\1" " "" '
>>> 

Zauważ, że nie jest to dokładnie to, o co prosiłeś, ponieważ zjada wiele cudzysłowów z obu końców ciągu!

pihentagy
źródło
Doskonale służy mojemu celowi! Wielkie dzięki.
Harsh Wardhan
4

Jeśli jesteś pewien, że na początku i na końcu znajduje się znak „, który chcesz usunąć, po prostu zrób:

string = string[1:len(string)-1]

lub

string = string[1:-1]
TooAngel
źródło
2

Usuń określony ciąg z początku i końca z ciągu.

s = '""Hello World""'
s.strip('""')

> 'Hello World'
nsantana
źródło
1

Mam kod, który musi usuwać pojedyncze lub podwójne cudzysłowy, a nie mogę go po prostu ast.literal_eval.

if len(arg) > 1 and arg[0] in ('"\'') and arg[-1] == arg[0]:
    arg = arg[1:-1]

Jest to podobne do odpowiedzi ToolmakerSteve, ale zezwala na ciągi o długości 0 i nie zamienia pojedynczego znaku "w pusty ciąg.

dbn
źródło
0

w twoim przykładzie możesz użyć listwy, ale musisz zapewnić przestrzeń

string = '"" " " ""\\1" " "" ""'
string.strip('" ')  # output '\\1'

zwróć uwagę, że \ 'w wyjściu to standardowe cudzysłowy Pythona dla danych wyjściowych w postaci łańcuchów

wartość twojej zmiennej to „\\ 1”

RomainL.
źródło
0

Funkcja poniżej usunie puste elementy i zwróci ciągi bez cudzysłowów. Jeśli nie ma cudzysłowów, zwróci ten sam ciąg (pozbawiony)

def removeQuote(str):
str = str.strip()
if re.search("^[\'\"].*[\'\"]$",str):
    str = str[1:-1]
    print("Removed Quotes",str)
else:
    print("Same String",str)
return str
Sumer
źródło
0

Począwszy od Python 3.9, możesz używać removeprefixi removesuffix:

'"" " " ""\\1" " "" ""'.removeprefix('"').removesuffix('"')
# '" " " ""\\1" " "" "'
Xavier Guihot
źródło
-1

znajdź pozycję pierwszego i ostatniego ”w ciągu

>>> s = '"" " " ""\\1" " "" ""'
>>> l = s.find('"')
>>> r = s.rfind('"')

>>> s[l+1:r]
'" " " ""\\1" " "" "'
remosu
źródło