将文本标记放在字符串中是否不好?有其他选择吗?


10

我使用大量字符串,需要大量操作。

例如,我可能会生成这样的字符串:

第1部分

A节
编程

第2部分
用于编程的分区船。

AA
节SQL条目。

该字符串太大,无法手动检查它的每个部分。现在,我需要split将此string分为stringlist几个部分。我可以想到两种选择:

正则表达式:

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

看起来应该可以,但是有时会漏掉一些异常(即:Section SQL Entries错误地分裂)

否则,我可以做的就是在生成初始字符串时放置一个标记:

🚤💻Part1

AA节
编程

🚤💻第2部分
用于编程的分区船。

A
第AA 节“ SQL条目”。

这意味着分割字符串将变得容易:

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

有人告诉我,这些都不是好的样式或编程实践,但是直到现在我还没有讨论它,也没有找到替代方法。

  • 如果您是我的项目经理,您会接受这两种方法吗?
  • 如果没有,您会建议我做为最佳做法吗?

6
如果您的程序知道将这些标记放置在何处,为什么不将这些部分生成为单独的字符串开头呢?
雅各布·赖勒

我认为用户使用的标记无法很好地转换为您当前的编码并不是一个好主意。
图兰斯·科尔多瓦

2
实际使用的符号在很大程度上是无关紧要的,要有所作为的是您要解析的事物的语法
jk。

4
@Akiva您确定性能受到打击吗?在任何情况下,您都使用相同数量的数据,我怀疑会存在显着差异。将数千个功能组合为一个功能,循环调用该功能,并进行一些测量。
雅各布·赖勒

2
@Akiva 在最坏的情况下,检索和替换列表中的元素应该等同于拆分大字符串。
雅各布·赖勒

Answers:


17

将文档编码嵌入为字符串形式的文本不是坏习惯。考虑一下markdown,HTML,XML,JSON,YAML,LaTeX等。

坏习惯是重新发明轮子。与其编写自己的文本处理器,不如考虑使用现有标准。有很多免费软件可以为您进行大量分析,并且许多软件都具有非限制性许可证,可让您在自己的专有软件中使用所述软件。


就我而言,我正在发明一个轮子,如果我想做的是为降价语言构建一个独特的解释器。例如,我的一个项目是将Latex解释为人耳可读的SSML:meta.wikimedia.org/wiki/Grants : IdeaLab/…。<<该URL的末尾有一个句点,否则它将不起作用
Akiva

2
@Akiva我必须使用由工作场所开发的自定义文本格式,从字面上重新发明轮子。我必须为此维护3种语言(Javascript,Java和Objective-C)的4个解析器,这是一场恶梦现在做正确的事,废除这种自定义文本格式。我不能强调不够多么庞大的一个维护的噩梦,这将成为几年的道路。利用现有的结构化格式,XML,JSON等
克里斯Cirefice

@ChrisCirefice能给我一个噩梦的例子吗?
Akiva

1
@Akiva我认为您甚至必须维护一个解析器(在我的情况下为几种,并且使用不同的语言)的事实令人恐惧。存在标准格式是有原因的-它们可以表示您需要的数据-无需费力,因为这些解析器已经过构建,优化和维护。自定义文本格式也是非常专业的知识,这意味着通常只有一两个开发人员会足够熟悉该格式以成功维护它。那应该可以说。大多数人都熟悉CML,JSON,很少有人知道自定义格式。
克里斯·西里菲斯

1
@Akiva确实!Markdown格式(SE和其他许多网站用于文本格式设置)在某种程度上标准的,就像SQL一样。但是自定义扩展名(例如SE)有很多不同的“风味”。有一个解析“核心”的标准库,然后,如果需要其他功能,则可以扩展该库。但是,构建和维护自己的格式化程序会很荒谬-已经存在一些格式化程序(markdown,BB代码等),那么为什么要重新发明轮子并维护所有这些代码呢?也可以只使用现有的库:)
Chris Cirefice

8

拆分较大的任意字符串时,使用一些公共分隔符应该可以正常工作,但是我建议不要使用任意符号。将该字符串读为纯文本的人可能会感到困惑,更不用说UTF带来的麻烦以及该符号是否出现在各节内。

其中最重要的部分是每个节都保持完整,而每个“节头”都需要适当地标识。

为什么不使用公共分隔符但保持可读性呢?就像是:

[SECTION]
Part 1
Boat

[SECTION]
Section A
Programming

[SECTION]
Part 2
Partitioning boats for programming.

[SECTION]
Section AA
Section SQL Entries.

问题在于确定分隔符应该是什么,因为分隔符必须保证不会出现任何部分。您可以通过要求它位于行的开头并且该只有文本,来进一步将其标识为分隔符

如果没有进一步了解每个部分需要什么文本,就很难就在这种情况下哪种通用分隔符是最好的提出建议。


我喜欢您的回答强调可读性。这些字符串是通过数据抓取用户生成的文本(例如SE中用于编写问题和答案的标记语言)生成的。因此,您可以轻松想象什么类型的字符串处理问题可能会起作用。
Akiva

5

接受的答案似乎错过了您在评论中写的内容:

原因是我做的很多操作都需要完整的字符串

并以此为例:

s.replace(“ boat”,“ programming”);

如果这是您想要的,恕我直言,在整个字符串中使用一些“ markdown”或文本分隔符是一个非常糟糕的主意,这总是有一定的干扰操作的风险,并且不会导致健壮的代码。特别是当您尝试在这样的组合字符串上开始使用正则表达式时,您可能会遇到人们在尝试使用正则表达式解析HTLM或XML时遇到的相同问题。

尤其是因为您撰写的内容可能有“成千上万的[此类操作]功能”,所以这种风险可能会成为一个真正的问题。即使您使用诸如XML之类的markdown在内部存储字符串列表,也需要确保该操作仅处理内容,而不处理markdown,因此这意味着在执行任何处理之前将字符串拆分成多个部分并加入它后来又-所以将有给你表现不佳的高风险。

这里更好的设计替代方案是提供一个抽象数据类型(如果愿意,可以使用一个类),让其调用它MyStringList,并提供一小组基本操作,这些操作可以使您根据该操作实现“数千个函数”。例如,可能存在泛型findreplace操作,或泛型功能map操作JoinToString如果确实需要某些字符串的整个列表在一个字符串中,则还可以添加类似操作的内容。

使用这些操作,您担心代码变得更加复杂,因为“必须在for循环中完成所有工作”变得毫无意义,因为for您获得的唯一循环封装在数据类型的操作中。在您对性能产生实际的,可衡量的影响之前,我不会担心性能(如果您正确实施基本操作,我会怀疑您是否会受到影响)。


支持,因为我确实创建了类似的东西。它允许我设置自定义的括号,例如<>,它将捕获该字符串的每个实例,在这里我可以轻松删除不需要的实例,并以自己想要的方式对其进行简洁地操作。这样做很好,因为正则表达式本身不会处理这样的子字符串:<boat <programming>>在有多个括号的地方。
Akiva


0

例如,我可能会生成这样的字符串:

问题:您从什么“生成”此字符串?

请问是任何容易操纵?


字符串是从网站中的Datascraping用户内容中生成的。
Akiva

1
这不是从网站上检索数据的可靠方法,仅因为它们发生了变化并且事物四处移动或完全消失。从某种已发布的(因此可靠的)API检索数据会好得多。此外,许多商业网站的使用特别禁止这种事情。
Phill W.

有时我没有选择对我有价值的数据,因此始终需要对您正在查看的内容进行完整性检查,或者只是做出妥协并希望获得最好的结果。例如:我写了一个LaTeXto SSML解释器,问题之一是您可以使用完全不同的代码生成相同的图像,因此,如果用户选择不良或深奥的方式生成公式,则几乎不可能保持一致。总而言之,这就是说,不善于实践的人们不会对自己的剧本有一个体面的解释。
Akiva
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.