ฉันจะแทนที่ช่องว่างด้วยการขีดเส้นใต้และในทางกลับกันได้อย่างไร


221

ฉันต้องการแทนที่ช่องว่างด้วยการขีดเส้นใต้ในสตริงเพื่อสร้าง URL ที่ดี ตัวอย่างเช่น:

"This should be connected" becomes "This_should_be_connected" 

ฉันใช้ Python กับ Django สิ่งนี้สามารถแก้ไขได้ด้วยการแสดงออกปกติ?


1
สิ่งนี้สามารถทำได้ในเทมเพลต django มีวิธีใดในการลบช่องว่างสีขาว มีแท็ก / ตัวกรองในตัวเพื่อทำสิ่งนี้หรือไม่? หมายเหตุ: slugifyไม่ได้ให้ผลลัพธ์ที่ต้องการ
user1144616

คำตอบ:


375

คุณไม่ต้องการการแสดงออกปกติ Python มีวิธีสตริงในตัวที่ทำสิ่งที่คุณต้องการ:

mystring.replace(" ", "_")

29
สิ่งนี้ไม่สามารถใช้ได้กับอักขระช่องว่างอื่น ๆ เช่น \ t หรือช่องว่างไม่แตก
Roberto Bonvallet

12
ใช่คุณถูกต้อง แต่เพื่อจุดประสงค์ของคำถามที่ถามคุณไม่จำเป็นต้องคำนึงถึงช่องว่างอื่น ๆ
rogeriopvl

1
ฉันต้องนำเข้าทุกอย่างเพื่อใช้งานได้หรือไม่ ฉันได้รับข้อผิดพลาดต่อไปนี้: AttributeError: วัตถุ 'builtin_function_or_method' ไม่มีแอตทริบิวต์ 'แทนที่'
Ocasta Eshu

2
อาจเป็นตัวแปรที่คุณเรียกว่าแทนที่ไม่ใช่ประเภทสตริง
Snigdha Batra

5
คำตอบนี้อาจสับสนได้ดีกว่าเขียนมันเป็น mystring = mystring.replace ("", "_") เพราะมันไม่ได้แก้ไขสตริงโดยตรง แต่แทนที่จะส่งกลับรุ่นที่เปลี่ยนแปลง
Mehdi

79

การแทนที่ช่องว่างนั้นใช้ได้ แต่ฉันอาจแนะนำให้เพิ่มอีกเล็กน้อยเพื่อจัดการอักขระ URL ที่ไม่เป็นมิตรอื่น ๆ เช่นเครื่องหมายคำถามเครื่องหมายวรรคตอนเครื่องหมายอัศเจรีย์และอื่น ๆ

นอกจากนี้โปรดทราบว่าฉันทามติทั่วไปในหมู่ผู้เชี่ยวชาญด้าน SEO คือการใช้เครื่องหมายขีดกลางเพื่อขีดเส้นใต้ใน URL

import re

def urlify(s):

    # Remove all non-word characters (everything except numbers and letters)
    s = re.sub(r"[^\w\s]", '', s)

    # Replace all runs of whitespace with a single dash
    s = re.sub(r"\s+", '-', s)

    return s

# Prints: I-cant-get-no-satisfaction"
print(urlify("I can't get no satisfaction!"))

สิ่งนี้น่าสนใจ ฉันจะใช้คำแนะนำนี้อย่างแน่นอน
Lucas

จำไว้ว่าให้ urllib.quote () ผลลัพธ์ของ urlify ของคุณ () - จะเกิดอะไรขึ้นถ้า s มีบางสิ่งที่ไม่ใช่ ASCII?
zgoda

1
นี่เป็นสิ่งที่ดี - แต่ RE แรกที่มี \ W จะลบช่องว่างด้วยผลลัพธ์ที่ RE ที่ตามมานั้นไม่มีอะไรที่จะมาแทนที่ ... หากคุณต้องการแทนที่ตัวละครอื่นของคุณด้วย '-' ระหว่างโทเค็นจะมี RE แรกแทนที่ด้วย พื้นที่เดียวตามที่ระบุไว้ - คือ s = re.sub (r "\ W", '& nbsp' s) (ซึ่งอาจจะเป็นรูปแบบปัญหา shonky ใน StackOverflow: meta.stackexchange.com/questions/105507/... )
tiluki

2
@Triptych คุณหมายถึงอะไร? กลืนแอฟริกาหรือยุโรป?
tiluki

1
ปัญหาเล็กน้อยอีกข้อนี้คือคุณลบเครื่องหมายยัติภังค์ที่มีอยู่แล้วใด ๆ ใน url ดังนั้นหากผู้ใช้พยายามทำความสะอาดสตริง url ก่อนที่จะอัปโหลดเป็น this-is-clean มันจะถูกปล้นลงในiscryptนี้ ดังนั้น s = re.sub (r '[^ \ w \ s-]', '', s) สามารถไปอีกขั้นตอนหนึ่งและลบช่องว่างนำหน้าและต่อท้ายเพื่อให้ชื่อไฟล์ไม่สิ้นสุดหรือเริ่มต้นด้วยเครื่องหมายยัติภังค์ที่มี s = re.sub (r '[^ \ w \ s-]', '', s) .strip ()
Intenex

42

Django มีฟังก์ชัน 'slugify' ซึ่งทำสิ่งนี้รวมถึงการเพิ่มประสิทธิภาพที่เป็นมิตรกับ URL อื่น ๆ มันถูกซ่อนอยู่ในโมดูลตัวกรองเริ่มต้น

>>> from django.template.defaultfilters import slugify
>>> slugify("This should be connected")

this-should-be-connected

นี่ไม่ใช่ผลลัพธ์ที่คุณต้องการ แต่ IMO เหมาะสำหรับใช้ใน URL


นั่นเป็นตัวเลือกที่น่าสนใจ แต่นี่เป็นเรื่องของรสนิยมหรือสิ่งที่เป็นประโยชน์ของการใช้ยัติภังค์แทนขีดล่าง ฉันเพิ่งสังเกตเห็นว่า Stackoverflow ใช้ยัติภังค์อย่างที่คุณแนะนำ ตัวอย่างเช่น digg.com ใช้ขีดล่าง
Lucas

นี่เป็นตัวเลือกที่ต้องการ (AFAIK) นำสตริงของคุณ slugify เก็บไว้ใน SlugField และใช้มันใน get_absolute_url ของแบบจำลองของคุณ คุณสามารถหาตัวอย่างบนอินเทอร์เน็ตได้อย่างง่ายดาย
shanyu

3
@Lulu คนใช้เครื่องหมายขีดคั่นเพราะเครื่องมือค้นหาถือว่าเครื่องหมายขีดคั่นเป็นตัวคั่นคำเป็นเวลานานดังนั้นคุณจะได้รับเวลาที่ง่ายขึ้นในการค้นหาหลายคำ
James Bennett

@Daniel Roseman ฉันสามารถใช้กับตัวแปรแบบไดนามิก เพราะฉันได้รับเว็บไซต์แบบไดนามิกเป็นสตริงในการตรวจสอบ
ephemeral

นี่คือคำตอบที่ถูกต้อง คุณต้องทำให้ URL ของคุณถูกสุขลักษณะ
kagronick

40

สิ่งนี้คำนึงถึงอักขระว่างอื่น ๆ นอกเหนือจากที่ว่างและฉันคิดว่าเร็วกว่าการใช้reโมดูล:

url = "_".join( title.split() )

4
ที่สำคัญจะใช้กับอักขระช่องว่างหรือกลุ่มของอักขระช่องว่าง
dshepherd

วิธีนี้ไม่ได้จัดการกับอักขระช่องว่างทั้งหมด (เช่น\x8f)
Lokal_Profil

เยี่ยมมาก @Lokal_Profil! เอกสารไม่ได้ระบุตัวอักษรช่องว่างถูกนำเข้าบัญชี
xOneca

1
วิธีนี้จะไม่รักษาตัวคั่นซ้ำเนื่องจาก split () จะไม่ส่งคืนรายการเปล่าเมื่อใช้พฤติกรรม "split on whitespace" ที่เป็นค่าเริ่มต้น นั่นคือถ้าอินพุตคือ "สวัสดี (6 ช่องว่างที่นี่) โลก" สิ่งนี้จะส่งผลให้ "hello, _world" เป็นเอาต์พุตแทนที่จะเป็น "hello, ______ โลก"
FliesLikeABrick

20

ใช้reโมดูล:

import re
re.sub('\s+', '_', "This should be connected") # This_should_be_connected
re.sub('\s+', '_', 'And     so\tshould this')  # And_so_should_this

นอกจากว่าคุณมีช่องว่างหลายช่องหรือช่องว่างอื่น ๆ ที่เป็นไปได้ข้างต้นคุณอาจต้องการใช้string.replaceตามที่คนอื่นแนะนำ


ขอบคุณนี่คือสิ่งที่ฉันขอ แต่ฉันเห็นด้วย "string.replace" ดูเหมือนจะเหมาะกับงานของฉันมากกว่า
Lucas

อะไรคือสิ่งที่ฉันตั้งใจจะยกระดับสิ่งนี้ แต่ด้วยเหตุผลบางอย่างมันได้ถูกลดระดับลงและตอนนี้การลงคะแนนของฉันถูกล็อคอินขออภัย Jarret
Dave Liu

10

ใช้วิธีการแทนที่สตริง:

"this should be connected".replace(" ", "_")

"this_should_be_disconnected".replace("_", " ")


6

น่าแปลกที่ห้องสมุดนี้ยังไม่ได้กล่าวถึง

แพคเกจหลามชื่อ python-slugify ซึ่งทำได้ค่อนข้างดีในการเป็น slugifying:

pip install python-slugify

ทำงานเช่นนี้:

from slugify import slugify

txt = "This is a test ---"
r = slugify(txt)
self.assertEquals(r, "this-is-a-test")

txt = "This -- is a ## test ---"
r = slugify(txt)
self.assertEquals(r, "this-is-a-test")

txt = 'C\'est déjà l\'été.'
r = slugify(txt)
self.assertEquals(r, "cest-deja-lete")

txt = 'Nín hǎo. Wǒ shì zhōng guó rén'
r = slugify(txt)
self.assertEquals(r, "nin-hao-wo-shi-zhong-guo-ren")

txt = 'Компьютер'
r = slugify(txt)
self.assertEquals(r, "kompiuter")

txt = 'jaja---lol-méméméoo--a'
r = slugify(txt)
self.assertEquals(r, "jaja-lol-mememeoo-a") 

5

ฉันใช้รหัสต่อไปนี้สำหรับ URL ที่เป็นมิตรของฉัน:

from unicodedata import normalize
from re import sub

def slugify(title):
    name = normalize('NFKD', title).encode('ascii', 'ignore').replace(' ', '-').lower()
    #remove `other` characters
    name = sub('[^a-zA-Z0-9_-]', '', name)
    #nomalize dashes
    name = sub('-+', '-', name)

    return name

มันทำงานได้ดีกับตัวยูนิโค้ดเช่นกัน


1
คุณช่วยอธิบายได้ไหมว่าสิ่งนี้แตกต่างจากฟังก์ชั่น slugify Django ในตัวหรือไม่
Andy Baker

4

Python มีวิธีการในตัวบนสายอักขระที่เรียกว่า replace ซึ่งจะใช้ดังนี้:

string.replace(old, new)

ดังนั้นคุณจะใช้:

string.replace(" ", "_")

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


3

OP ใช้ python แต่เป็นจาวาสคริปต์ (สิ่งที่ต้องระวังเนื่องจากไวยากรณ์มีความคล้ายคลึงกัน

// only replaces the first instance of ' ' with '_'
"one two three".replace(' ', '_'); 
=> "one_two three"

// replaces all instances of ' ' with '_'
"one two three".replace(/\s/g, '_');
=> "one_two_three"

3
mystring.replace (" ", "_")

หากคุณกำหนดค่านี้ให้กับตัวแปรใด ๆ มันจะทำงาน

s = mystring.replace (" ", "_")

โดยค่าเริ่มต้น mystring จะไม่มีสิ่งนี้



-3
perl -e 'map { $on=$_; s/ /_/; rename($on, $_) or warn $!; } <*>;'

จับคู่และแทนที่ช่องว่าง> ขีดล่างของไฟล์ทั้งหมดในไดเรกทอรีปัจจุบัน

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