Metin işaretlerini dizelerin içine yerleştirmek kötü bir stil mi? Bir alternatif var mı?


10

Çok fazla manipülasyon gerektiren büyük dizelerle çalışıyorum.

Örneğin, böyle bir dize oluşturabilir:

Bölüm 1
Tekne

Bölüm A
Programlama

Bölüm 2
Programlama için tekneleri bölme.

Bölüm AA
Bölüm SQL Girişleri.

Dize, her parçasını manuel olarak kontrol etmek için çok büyük olacaktır. Şimdi gerek splitbu stringbir içine stringlistbölümleri ve parçaları tarafından. İki seçeneği düşünebilirim:

Düzenli Bir İfade:

QStringList sl = s.split(QRegularExpression("\n(?=Part [0-9]+|Section [A-Z]+)"));

Çalışması gerektiği gibi görünüyor, ancak bazen istisnalar geçiyor (IE: Section SQL Entriesyanlışlıkla bölünecek)

Aksi takdirde ne yapabilirim ilk dize oluştururken bir işaretleyici yerleştirmektir:

1 Bölüm 1
Tekne

Bölüm A
Programlama

Bölüm 2
Bölüm Programlama için bölme tekneleri.

AABölüm AA
Bölümü SQL Girişleri.

Bu, dizeyi bölmenin kolay olacağı anlamına gelir:

QStringList sl = s.split("🚤💻"));

Bir şey bana, bunların hiçbirinin iyi bir stil veya programlama pratiği olmadığını söylüyor, ancak bu noktaya kadar tartışmadım veya bir alternatif bulamadım.

  • Proje yöneticim olsaydınız, bu yöntemlerden birini kabul eder misiniz?
  • Değilse, en iyi uygulama olarak ne yapmamı önerirsiniz?

6
Programınız bu işaretleyicileri nereye yerleştireceğinizi biliyorsa, neden bölümleri başlamak için ayrı dizeler olarak oluşturmuyorsunuz?
Jacob Raihle

Kullanıcı mevcut kodlama iyi çevirmek bir marker iyi bir fikir olduğunu sanmıyorum.
Tulains Córdova

2
kullanılan gerçek semboller büyük ölçüde ilgisizdir, fark yaratacak olan, ayrıştırmaya çalıştığınız şeyin dilbilgisidir
jk.

4
@Akiva performans vuruşundan emin misiniz? Her halükarda aynı miktarda veri ile çalışıyorsunuz, önemli bir fark olacağından şüpheliyim. Binlerce işlevi tek bir işlevde oluşturun, bir döngüde çağırın ve bazı ölçümler yapın.
Jacob Raihle

2
@Akiva Listedeki öğeleri almak ve değiştirmek en kötü ihtimalle büyük bir dizeyi bölmekle karşılaştırılabilir olmalıdır .
Jacob Raihle

Yanıtlar:


17

Belge kodlamasının bir dizeye metin olarak gömülmesi kötü bir uygulama değildir. İşaretleme, HTML, XML, JSON, YAML, LaTeX vb.

Kötü uygulama, tekerleği yeniden icat etmektir. Kendi metin işlemcinizi yazmak yerine, mevcut bir standardı kullanmayı düşünün. Ayrıştırma işleminin çoğunu sizin için yapan çok sayıda ücretsiz yazılım vardır ve çoğunun söz konusu yazılımı kendi özel yazılımınızda kullanmanıza izin veren kısıtlayıcı olmayan bir lisansı vardır.


Benim durumumda, bir tekerlek icat ediyorum, eğer yapmaya çalıştığım bir işaretleme dili için benzersiz bir tercüman oluşturmaksa. Örneğin, projelerimden biri Lateks'i insan kulağı tarafından okunabilen SSML olarak yorumluyordu: meta.wikimedia.org/wiki/Grants:IdeaLab/… . << Bu URL'nin sonunda bir süre var, aksi halde çalışmaz
Akiva

2
@Akiva İşyerim tarafından geliştirilen ve tekerleği tam anlamıyla yeniden icat eden özel bir metin formatıyla çalışmak zorundayım. Bunun için 3 dilde 4 ayrıştırıcı (Javascript, Java ve Objective-C) bulundurmam gerekiyor ve bu korkunç bir kabus . Şimdi doğru olanı yapın ve bu özel metin biçimi saçmalığını kaldırın . Bakım kabusunun bu kadar büyük bir yolun ne kadar büyük olacağını vurgulayamam . Mevcut yapılandırılmış formatları, XML, JSON, vb.
Kullanın

@ChrisCirefice Bana bunun nasıl bir kabus olduğuna dair bir örnek verebilir misiniz?
Akiva

1
@Akiva Sanırım bir ayrıştırıcıyı (benim durumumda birkaç ve farklı dillerde) korumak zorunda olduğunuz gerçeği dehşet verici. Bir nedenden ötürü standart formatlar mevcuttur - ihtiyaç duyduğunuz verileri temsil edebilirler - ve sizin açınızdan çok az çaba sarf ederler, çünkü bu ayrıştırıcılar inşa edilmiş, rafine edilmiş ve korunmuştur. Özel metin biçimi de son derece uzmanlaşmış bir bilgidir, yani genellikle yalnızca bir veya iki geliştiricinin bunu başarıyla sürdürecek biçime aşina olacağı anlamına gelir. Ciltler konuşmalı. Çoğu kişi CML, JSON'a aşinadır - çok azı özel biçimleri bilir.
Chris Cirefice

1
@Akiva Gerçekten! Markdown formatı (SE ve diğer birçok sitenin metin formatlama için kullandığı), SQL gibi biraz standarttır . Ancak özel uzantılara sahip birçok farklı 'lezzet' vardır (örneğin SE gibi). 'Çekirdeği' ayrıştıran standart bir kütüphane var, ek özellikler istiyorsanız kütüphaneyi genişletiyorsunuz. Ancak, kendi biçimlendiricinizi oluşturmak ve korumak gülünç olurdu - bazıları zaten var (markdown, BB kodu, vb.), Neden tekerleği yeniden icat edip tüm bu kodu koruyorsunuz? Sadece mevcut bir kütüphaneyi de kullanabilirsiniz :)
Chris Cirefice

8

Bazı ortak ayırıcıların kullanılması daha büyük rasgele dizeleri ayırırken iyi çalışmalıdır, ancak keyfi bir sembol kullanılmasına karşı öneriyorum. Bu dizeyi düz metin olarak okuyan biri, UTF ile ilgili sorunlardan ve sembolün bölümlerin içinde görünüp görünmediğinden bahsetmemekle karıştırılabilir.

Bunun en önemli kısmı, her bölümün bozulmadan kalması ve her bir "bölüm başlığının" uygun şekilde tanımlanması gerektiğidir.

Neden ortak bir ayırıcı kullanmıyor ancak okunabilir halde kalsın? Gibi bir şey:

[SECTION]
Part 1
Boat

[SECTION]
Section A
Programming

[SECTION]
Part 2
Partitioning boats for programming.

[SECTION]
Section AA
Section SQL Entries.

Sorun, herhangi bir bölüm göstermemesi garanti edilen bir şey olması gerektiğinden, ayırıcının ne olması gerektiğine karar vermektir . Sen ayrıca bir olarak tanımlamak olabilir ayırıcı öyle isteyerek bir satırın başında ve o hat üzerinde sadece metin .

Her bölümde hangi metnin beklendiği hakkında daha fazla bilgi olmadan , bu durumda hangi ayırıcının en iyi olacağı konusunda bir öneri yapmak zordur .


Yanıtınızın okunabilirlik konusundaki vurgusunu seviyorum. Dizeler, örneğin SE'de soru ve cevap yazmak için kullanılan İşaretleme dili gibi kullanıcı tarafından oluşturulan metin kazıma verileri yoluyla oluşturulur. Böylece, ne tür dize manipülasyon sorunlarının devreye girebileceğini kolayca hayal edebilirsiniz.
Akiva

5

Kabul edilen cevap, bir yorumda yazdıklarınızı kaçırmış gibi görünüyor:

Bunun nedeni, yaptığım manipülasyonun çoğunun tam dizeyi gerektirmesidir

ve bunu örnek olarak verdim:

s.replace ("tekne", "programlama");

İstediğiniz buysa, IMHO, tüm dizeniz için bazı "işaretleme" veya metin ayırıcı kullanmak gerçekten kötü bir fikirdir, bu her zaman manipülasyona müdahale etmek için belirli bir risk taşır ve sağlam koda yol açmaz. Özellikle böyle bir birleşik dize üzerinde düzenli ifadeler kullanmaya başladığınızda, muhtemelen HTLM veya XML'i normal ifadelerle ayrıştırmaya çalışırken insanların karşılaştığı sorunlarla karşılaşırsınız .

Özellikle çünkü orada olabileceğini yazdı "[böyle manipülasyon] fonksiyonların binlerce", risk gerçek bir sorun haline gelebilir. Dize listesini dahili olarak saklamak için XML gibi bir işaretleme kullansanız bile, manipülasyonun işaretlemeyi değil yalnızca içeriği işleyeceğinden emin olmanız gerekir, böylece herhangi bir işlem yapmadan önce dizeyi parçalara bölmek ve katılmak daha sonradan tekrar - bu yüzden bu size kötü bir performans veren bir yüksek risk olacaktır.

Buradaki en iyi tasarım alternatifi, soyut bir veri türü sağlamak (isterseniz bir sınıf kullanmak), onu çağırmak MyStringListve "binlerce işlevinizi" bu işlemler açısından gerçekleştirmenize izin veren küçük bir temel işlemler kümesi sağlamaktır. Örneğin, genel findve replaceişlemler veya genel bir işlevsel mapişlem olabilir . Ayrıca JoinToString, belirli purporses için bir dizede tüm listeye gerçekten ihtiyacınız varsa , işlem gibi bir şey de ekleyebilirsiniz .

Bu işlemleri kullanarak, kodun daha karmaşık hale gelmesinden korkmanız, çünkü "her şey bir for döngüsü içinde yapılması gerekecek" anlamsız hale gelir, çünkü aldığınız tek fordöngüler veri tipinin işlemleri içinde kapsüllenir. Ve gerçek, ölçülebilir bir performans etkiniz olana kadar (temel işlemleri doğru bir şekilde uygularsanız alacağınızdan şüpheleniyorum) performanstan endişe etmem.


Oy verin çünkü böyle bir şey yarattım. Bu özel parantez söylemek kümesi beni tanır, <ve >, ve ben kolayca İstemediğim örneklerini kaldırmak ve temiz bir şekilde istediğim şekilde manipüle ki dizenin her örneğini çekecek. Bu iyidir çünkü düzenli ifadeler kendi başlarına böyle alt dizeleri işlemez: <boat <programming>>birden çok parantez katmanının olduğu yerlerde.
Akiva

1

Açıklanan biçim INI dosyalarına çok benzer:

https://en.wikipedia.org/wiki/INI_file

Bu durumda, bölüm köşeli parantez [] ile çevrelenir, bu nedenle açıkladığınız şey, metne ek anlam eklemek için bölümü bir şekilde işaretleyerek mantıklıdır.


0

Örneğin, böyle bir dize oluşturabilir:

Soru: Bu dizgiden ne üretiyorsunuz?

Misiniz o işlemek için daha kolay olacak?


Dize, bir web sitesindeki Datascraping kullanıcı içeriğinden oluşturulur.
Akiva

1
Bu, bir web sitesinden veri almanın güvenilir bir yolu değildir, çünkü bunlar değişir ve işler hareket eder veya tamamen kaybolur. Bir çeşit yayınlanmış (ve dolayısıyla güvenilir) API'den veri almaktan çok daha iyi olursunuz. Ayrıca, birçok ticari web sitesinin kullanımı bu tür şeyleri özellikle yasaklamaktadır.
Phill W.

Bazen hangi verilerin benim için değerli olduğunu seçemiyorum ve bu yüzden baktığınız şey için bütünlük kontrolleri yapmaya veya sadece en iyi şekilde basit uzlaşmaya ve umuma ihtiyaç duymaya ihtiyaç duyuyorum. Örneğin: Bir yazdım LaTeXiçin SSMLtercüman ve sorunlardan biri çok farklı kodla aynı görüntüleri üretebilir olduğunu ve kullanıcının kendi formülleri üretme kötü veya ezoterik yolları seçerse tutarlı olması neredeyse imkansız yani. Günün sonunda, iyi uygulama kullanmayan insanların senaryolarını iyi bir şekilde yorumlamayacakları anlamına gelir.
Akiva
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.