【问题标题】:Using JavaScript to process and rearrange a plain text nested list使用 JavaScript 处理和重新排列纯文本嵌套列表
【发布时间】:2015-08-03 21:08:29
【问题描述】:

我有一个纯文本数据文件,其中包含一个嵌套的项目列表,如下所示:

Group: Folder
    Group: Subfolder1
    Group: Subfolder2
Group: Folder2
    Group: Subfolder1
        Group: NestedSubfolder1

...等等。 (每个文件夹名称都会在列表中自动添加“组:”;文件夹也没有命名结构或约定,我将它们标记为 try 以避免使示例复杂化)此文件经常更新,因此不能手动修改它,而且我无法控制输出的排列/格式。

我正在使用的读取此文件的应用程序将其处理为大量(源代码长约四千行)单行文本,没有换行符或分隔符/分隔符,因此它最终看起来像这样:

Group: Folder        Group: Subfolder1        Group: Subfolder2    Group: Folder2        Group: Subfolder1            Group: NestedSubfolder

现在,这是我的问题。为了使用它需要进行格式化的方式是这样的:

Folder/Subfolder1
Folder/Subfolder2
Folder2/Subfolder1/NestedSubfolder1

对于我的正常用例,RegEx 或其他一些巧妙的过滤可以让我获得我需要的信息,但由于它没有分隔符、换行符或分隔符,并且需要自动复制文本并智能地粘贴到适当的位置,我有点不知所措。用于解析这些数据并对其采取行动的应用程序可以运行 JavaScript (Rhino) 脚本,因此理论上可以让应用程序运行将输出转换为格式正确、可用的纯文本的脚本。但是,我还不(完全)精通 JS;有没有人必须处理类似的任务,或者有任何聪明的想法来处理这种类型的列表,以便每个项目都包含它的完整路径?

【问题讨论】:

  • 除了第一个文件夹外,它看起来分解如下:每个文件夹前面有4个字符的空格,每个子文件夹有8个,每个嵌套的子文件夹有12个。它们增加了每次4。那么您是否尝试过使用正则表达式在每个文件夹名称后添加一个换行符,然后根据每行上的空白量进行解析?
  • 用“/”和“Group:\s+”替换换行+制表符。
  • @dandavis 我确实尝试过;不幸的是,它只处理子文件夹的第一个实例。因为父文件夹名称会留在第一个子文件夹的前面,所以没有为其余项目提供路径。例如,我在第一个实例中得到了“Folder/Subfolder1”,但第二个实例留下了“Subfolder2”,前面没有路径。
  • @zfrisch 我认为你绝对是在正确的轨道上;我现在正在尝试给自己上 JS 速成课程,这样我就可以弄清楚如何获取父文件夹名称,然后在每个后续项目中添加父名称,其中包含大量空格。然后,当下一行的空格数减少时迭代该过程。不确定我是否描述了最好的方法,但我认为这就是您的建议。
  • @vertigozero1 今天我会再看一下这个问题。不过要清楚一点,您需要将它正确格式化为第二个示例中的 folder\folder2\etc ,这是一个长字符串?还是从第一个嵌套换行符和间距的?

标签: javascript list rhino text-parsing


【解决方案1】:

这是一个小提琴http://jsfiddle.net/362oapjk/1/

<!DOCTYPE html>
<html>
<script src='http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'></script>
<script> 

//on window load:
window.onload = function() {

//save input text into variable toBeParsed
//we wrap the <pre> tag to make sure variable text keeps all spaces/line breaks

var toBeParsed = "<pre> " + $("#input").html() + " </pre>"; 

//these next lines replace groups of space using regEx
//to format the text

toBeParsed = toBeParsed.replace( /(\s{20}Group:\s)/g, "\\");
toBeParsed = toBeParsed.replace( /(\s{16}Group:\s)/g, "\\");
toBeParsed = toBeParsed.replace( /(\s{12}Group:\s)/g, "\\");
toBeParsed = toBeParsed.replace( /(\s{8}Group:\s)/g , "\\");
var parsed = toBeParsed.replace( /(\s{4}Group:\s)/g, "\n");

//insert parsed text into output section

$("#output").html(parsed);
}
</script> 
<pre><section id="input">
List of Folders
</section></pre>


<section id="output">
</section>
</html> 

您将文本粘贴到“输入”部分

当您打开网页时,它会采用预先格式化的输入文本并进行如下解析:

  1. 前面有 20 个空格的任何匹配“组:”替换为“\”。
  2. 前面有 16 个空格的任何匹配“组:”替换为“\”。
  3. 前面有 12 个空格的任何匹配“组:”替换为“\”。
  4. 前面有 8 个空格的任何匹配“组:”替换为“\”。
  5. 前面有 4 个空格的任何匹配“组:”替换为“\n”(换行符)。

顺序很重要,因为这些都是 4 的间隔。原因是,作为理解这个概念的一个假例子,如果您要解析 8 之前的 4 个空格,它会将其识别为 2 组,每组 4 个8 个。

这也意味着它取决于最长的子文件夹字符串是什么。此代码最多允许 4 个子文件夹。如果您需要更多,您将需要添加额外的正则表达式替换。 A.E. 这是现在的代码:

toBeParsed = toBeParsed.replace( /(\s{20}Group:\s)/g, "\\");
toBeParsed = toBeParsed.replace( /(\s{16}Group:\s)/g, "\\");
toBeParsed = toBeParsed.replace( /(\s{12}Group:\s)/g, "\\");
toBeParsed = toBeParsed.replace( /(\s{8}Group:\s)/g , "\\");
var parsed = toBeParsed.replace( /(\s{4}Group:\s)/g, "\n");

要添加第五个子文件夹,您需要添加另一行,另外还有 4 个空格(从 20 到 24)进行替换,如下所示:

toBeParsed = toBeParsed.replace( /(\s{24}Group:\s)/g, "\\");
toBeParsed = toBeParsed.replace( /(\s{20}Group:\s)/g, "\\");
toBeParsed = toBeParsed.replace( /(\s{16}Group:\s)/g, "\\");
toBeParsed = toBeParsed.replace( /(\s{12}Group:\s)/g, "\\");
toBeParsed = toBeParsed.replace( /(\s{8}Group:\s)/g , "\\");
var parsed = toBeParsed.replace( /(\s{4}Group:\s)/g, "\n");

此外,由于字符串中的第一个“Group: Folder”之前没有空格,因此您可以在输入部分的开头添加 4 个空格以获得干净的结果。 A.E.

//without spaces:
<pre><section id="input">Group: Folder        Group: SubFolder    Group: Folder2</section></pre>

//with spaces
<pre><section id="input">    Group: Folder       Group: SubFolder    Group: Folder2</section></pre>

这应该可以解决问题。

【讨论】:

  • 这很有帮助,尤其是您的详细描述!从这个角度来看,我明白了为什么到目前为止我的笨拙的脚本尝试都没有奏效。但是,此解决方案没有考虑到父级文件夹仅列出一次,这是真正的踢球者。因此,对于上面的示例输入,此脚本完美地处理“Folder2”,但如果有意义的话,将“SubFolder2”分组为“SubFolder1”的子级,而不是让它们都直接位于同一个父级“Folder”之下。跨度>
  • @vertigozero1 哈哈,很高兴它开始好转了!但是,是的,我明白你的意思(尽管我花了一点时间)我可能会在今天某个时候解决这个问题,并在我编辑答案时标记你。对不起。之前不太明白。
猜你喜欢
  • 1970-01-01
  • 2019-11-05
  • 2019-02-08
  • 2021-07-23
  • 2020-08-07
  • 1970-01-01
  • 1970-01-01
  • 2020-08-28
  • 1970-01-01
相关资源
最近更新 更多