引言
前面我们已经学会了随机抽取语料库,接下来我们来真正意义上的合成句子。
生成废话的样子
大概是这样
但是前面我们提取到的data是带有一定占位符的,首先我们就要完成占位符的替换。
占位符的替换
接下来我们来做占位符的替换,我们定义一个sentence的函数,然后传入两个参数,pick和replacer,其中,pick函数分为pickFamous,pickSaid.......等多种通过上一章的高阶函数创造的抽取废话的不同的部分,replacer则是要替换的对象
import { randomInt,randomFun } from "./random";
import fs from 'fs';
function sentence(pick, replacer) {
let ret = pick();
for(const key in replacer) {
ret = ret.replace(new RegExp(`{{${key}}}`, 'g'),
typeof replacer[key] === 'function' ? replacer[key]() : replacer[key]);
}
return ret;
}
上述函数通过传递参数即可完成句子的替换。
例如句子:"查尔斯·史{{said}},一个人几乎可以在任何他怀有无限热忱的事情上成功。{{conclude}}",
我们只需要传入pickFamous()和{said:pickSaid(),conclude:pickConclude()}即可通过上述的sentence()函数完成替换。
测试实例如下:
import { randomInt,randomFun } from "./random.js";
import fs from 'fs';
function sentence(pick, replacer) {
let ret = pick();
for(const key in replacer) {
ret = ret.replace(new RegExp(`{{${key}}}`, 'g'),
typeof replacer[key] === 'function' ? replacer[key]() : replacer[key]);
}
return ret;
}
// 下面为测试部分 用于测试句子的替换情况
fs.readFile('../resources/data.json',{encoding:"utf-8"},(err,dataStr)=>{
if(err){
console.log(err);
}
else {
dataStr = JSON.parse(dataStr);
const pickFamous = randomFun(dataStr.famous);
const pickConclude = randomFun(dataStr.conclude);
const pickSaid = randomFun(dataStr.said);
console.log(sentence(pickFamous,{said:pickSaid(),conclude:pickConclude()}));
}
})
还是切换到lib目录下,执行node article.js,即可打印出结果
培根说过,深窥自己的心,而后发觉一切的奇迹在你自己。这启发了我。
文章的生成
完成了占位符的替换部分,我们就可以来到最后一部分-----文章的生成了。
核心思路,通过上一章节的高阶函数生成几个废话部分的pick()函数,再通过上面的sentence()函数不断地生成句子,最后超出文章字数极大值的时候停止。
article.js全部代码如下:
import { randomInt,randomFun } from "./random.js";
function sentence(pick, replacer) {
let ret = pick();
for(const key in replacer) {
ret = ret.replace(new RegExp(`{{${key}}}`, 'g'),
typeof replacer[key] === 'function' ? replacer[key]() : replacer[key]);
}
return ret;
}
export function articleCreate(title, {
data
} = {},
cout
) {
const articleLength = cout;
const {famous, bosh_before, bosh, said, conclude} = data;
const [pickFamous, pickBoshBefore, pickBosh, pickSaid, pickConclude] = [famous, bosh_before, bosh, said, conclude].map((item) => {
return randomFun(item);
});
const article = [];
let totalLength = 0;
while(totalLength < articleLength) {
let section = '';
const sectionLength = randomInt(200, 500);
while(section.length < sectionLength || !/[。?]$/.test(section)) {
const n = randomInt(0, 100);
if(n < 20) {
section += sentence(pickFamous, {said: pickSaid, conclude: pickConclude});
} else if(n < 50) {
section += sentence(pickBoshBefore, {title}) + sentence(pickBosh, {title});
} else {
section += sentence(pickBosh, {title});
}
}
totalLength += section.length;
article.push(section);
}
return article;
}
代码有些复杂,我来解释一下
首先将articleCreate()export出去,然后定义一个articleLength用做接受文章长度,下一行的const {famous, bosh_before, bosh, said, conclude} = data;则是解构赋值传入的data(data是fs读取的语料库的数据)。接下来通过解构赋值加上createRandomPicker()函数完成pickFamous, pickBoshBefore, pickBosh, pickSaid, pickConclude几个函数的创建。
接下来创建article数组作为文章存储容器,totalLength 作为已有文章字数,通过totalLength和articleLength的比对完成while循环。section作为段落的变量,接下来通过一些句子剩余的判断生成不同长度的废话,然后判断其完整性和长度来添加标点符号。最后section添加到article中,返回出去。
当然可能说完这些还是有一些难度去理解,接下来我们通过一个简单的实例来测试这部分代码
接下来我们改造一下src目录下的index.js文件。
import fs from 'fs';
import {fileURLToPath} from 'url';
import path from 'path';
import {articleCreate} from '../lib/article.js';
const fileURL = import.meta.url;
const pathURL = fileURLToPath(fileURL);
const dirname = path.resolve(pathURL,"../");
const filePath = path.resolve(dirname,"../","resources/data.json");
fs.readFile(filePath,{encoding:"utf-8"},(err,dataStr)=>{
if(err){
console.log(err);
}
else{
const data = JSON.parse(dataStr);
const article = articleCreate('今天吃什么',{data},100);
console.log(article[0]);
}
})
前面的代码在准备部分就已经说过,这里就不多赘述了,主要是我import了article.js文件中的articleCreate()函数,然后向里传入了三个参数,最终生成了一篇长度为一百的,标题为 今天吃什么的文章。
输出的文章内容如下:
而这些并不是完全重要,更加重要的问题是,我认为,今天吃什么,到底应该如何实现。 培根说过,深窥自己的心,而后发觉一切的奇迹在你自己。这不
禁令我深思。 既然如此,今天吃什么,到底应该如何实现。 查尔斯·史说过一句著名的话,一个人几乎可以在任何他怀有无限热忱的事情上成功。这启发
了我。今天吃什么,到底应该如何实现。 今天吃什么,到底应该如何实现。 培根说过,深窥自己的心,而后发觉一切的奇迹在你自己。这启发了我。今天
吃什么,到底应该如何实现。 今天吃什么,到底应该如何实现。 我认为,今天吃什么,到底应该如何实现。 培根说过,深窥自己的心,而后发觉一切的
奇迹在你自己。这启发了我。我认为,今天吃什么,到底应该如何实现。 我认为,今天吃什么,到底应该如何实现。 培根说过,深窥自己的心,而后发觉
一切的奇迹在你自己。这启发了我。培根说过,深窥自己的心,而后发觉一切的奇迹在你自己。这启发了我。
可见我们的代码已经实现了生成废话文章的效果。
明天后天继续更新,现在的文章生成器只能接受我们的手动改的死数据,并不能交互,接下来的部分我会更新控制台交互版的文章生成器和网页版的文章生成器。