前言
本文将从零开始,讲解如何使用Node.js来实现一个文章生成器
node里面有很多优秀的模块,现在我们就借助node的fs模块来操控文本,来实现我们想要的效果
效果展示
- 体验 fs
首先我们先创建一个json文件
里面放一些内容
接下来我们书写代码
import fs from "fs";
const data = fs.readFileSync("./cuepus/data.json", "utf-8", (err, data) => {
if (!err) {
// console.log(data);
} else {
console.log(err);
}
});
可以看到我们就能读取到文件里的数据,这里我们体验了fs里面强大的功能
在这里我们放了文章的一些必须点,如文章内容、标题等,通过随机拿取数据生成一个文章
这里我们通过
import { fileURLToPath } from "url";
import { dirname,resolve } from "path";
去操控获取绝对路径
const url = import.meta.url;// 获取当前文件的绝对路径
console.log(url);
console.log(fileURLToPath(url));
console.log(dirname(fileURLToPath(url)));
// 获取文件的绝对路径
const path = resolve(dirname(fileURLToPath(url)), "./cuepus/data.json"); console.log(path);
const url = import.meta.url;
:使用了import.meta
对象来获取当前模块文件的绝对 URL 路径,并将其赋值给变量url
。console.log(fileURLToPath(url));
:将url路径转换为文件系统路径console.log(dirname(fileURLToPath(url)));
:将url转换为文件系统路径,然后通过dirname
函数获取该路径的目录部分const path = resolve(dirname(fileURLToPath(url)), "./cuepus/data.json");
:将前面获取到的目录部分和相对路径"./cuepus/data.json"
进行组合,生成一个完整的文件绝对路径,并将其赋值给变量path
。
接下来我们代码就可以写成以下的形式
import fs from "fs";
import { fileURLToPath } from "url";
import { dirname,resolve } from "path";
const url = import.meta.url;// 获取当前文件的绝对路径
// 获取文件的绝对路径
const path = resolve(dirname(fileURLToPath(url)), "./cuepus/data.json");
const data = fs.readFileSync(path, "utf-8", (err, data) => {
if (!err) {
// console.log(data);
} else {
console.log(err);
}
});
console.log(JSON.parse(data));
接下来我们写封装两个函数
random.js
export function randomInt(min, max) {
const n = Math.random()
return Math.floor(min * (1 - n) + max * n)
}
export function createRandomPicker(arr) {
arr = [...arr]
function randomPick() {
const len = arr.length - 1
const index = randomInt(0, len);
[arr[index], arr[len]] = [arr[len], arr[index]]
return arr[index]
}
randomPick() // 放弃第一次结果
return randomPick
}
首先,定义了一个名为 randomInt
的导出函数,它接受两个参数 min
和 max
,用于生成指定范围内的随机整数。
然后,定义了一个名为 createRandomPicker
的导出函数,它接受一个数组 arr
作为参数。
在函数内部,先对传入的数组进行了复制,以避免修改原始数组。
接着,定义了一个内部函数 randomPick
,它的功能是:
- 计算数组的有效长度。
- 生成一个在有效范围内的随机索引。
- 通过交换将随机索引处的元素与最后一个元素交换位置。
- 返回交换后的随机索引处的元素。
在函数体中,首先调用了一次 randomPick
函数,但放弃了这次的结果。
最后,返回 randomPick
函数,以便外部可以调用它来获取随机抽取的数组元素。
generator.js
import { randomInt, createRandomPicker } 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 generate(title, { corpus, min = 500, max = 800 }) {
const articleLenth = randomInt(min, max)
const { famous, bosh_before, bosh, conclude, said } = corpus
const [pickFamous, pickBoshBefore, pickBosh, pickConclude, pickSaid]
= [famous, bosh_before, bosh, conclude, said].map(createRandomPicker)
const article = []
let totalLength = 0
while (totalLength < articleLenth) { // 生成文章
let section = ''
const sectionLength = randomInt(100, 300)
while (section.length < sectionLength) { // 生成段落
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
}
从 './random.js'
模块导入了 randomInt
和 createRandomPicker
两个函数。
然后,定义了 sentence
函数,它接受两个参数 pick
和 replacer
。
pick
函数用于获取一个句子,然后通过遍历 replacer
对象中的键,使用正则表达式匹配并替换句子中特定的模板字符串(形如 {{key}}
)。如果对应的值是函数,则调用函数获取结果进行替换,否则直接使用值进行替换。
接下来,定义了 generate
函数,它接受三个参数:title
、一个包含配置信息的对象(包含 corpus
以及可选的 min
和 max
)。
在函数内部:
- 通过
randomInt
生成一个在min
和max
范围内的文章长度articleLenth
。 - 从
corpus
对象中解构出几个部分,并对每个部分使用createRandomPicker
函数创建随机选择器。 - 通过一个循环生成文章内容,每次循环生成一个段落。在生成段落的过程中,根据随机数决定使用不同的句子生成方式,并通过
sentence
函数进行处理和组合。 - 不断累加段落的长度,直到总长度达到
articleLenth
,最终将生成的文章段落组成一个数组返回。
最后调用即可,修改index.js
import fs from 'fs'
import { fileURLToPath } from 'url'
import { dirname, resolve } from 'path'
import { generate } from './lib/generator.js'
import { createRandomPicker } from './lib/random.js'
function loadCorpus(src) {
const url = import.meta.url // 读取当前脚本的绝对路径
const path = resolve(dirname(fileURLToPath(url)), src)
const data = fs.readFileSync(path, {encoding: 'utf8'})
return JSON.parse(data)
}
const corpus = loadCorpus('curpus/data.json')
const pickTitle = createRandomPicker(corpus.title)
const title = pickTitle()
const article = generate(title, { corpus })
fs.writeFileSync(`./output/${title}.txt`, article.join(''));
总结
本文本文将从零开始,讲解如何使用Node.js来实现一个文章生成器
希望看到这里的你能够有所收获!!!!自己动手实现一个简易的文章生成器吧
后期可以结合AI去实现更加智能的文章生成器