使用Node.js實(shí)現(xiàn)一個(gè)文章生成器
前言
本文將從零開始,講解如何使用Node.js來(lái)實(shí)現(xiàn)一個(gè)文章生成器
node里面有很多優(yōu)秀的模塊,現(xiàn)在我們就借助node的fs模塊來(lái)操控文本,來(lái)實(shí)現(xiàn)我們想要的效果
效果展示
- 體驗(yàn) fs
首先我們先創(chuàng)建一個(gè)json文件
里面放一些內(nèi)容
接下來(lái)我們書寫代碼
import fs from "fs"; const data = fs.readFileSync("./cuepus/data.json", "utf-8", (err, data) => { if (!err) { // console.log(data); } else { console.log(err); } });
可以看到我們就能讀取到文件里的數(shù)據(jù),這里我們體驗(yàn)了fs里面強(qiáng)大的功能
在這里我們放了文章的一些必須點(diǎn),如文章內(nèi)容、標(biāo)題等,通過(guò)隨機(jī)拿取數(shù)據(jù)生成一個(gè)文章
這里我們通過(guò)
import { fileURLToPath } from "url"; import { dirname,resolve } from "path";
去操控獲取絕對(duì)路徑
const url = import.meta.url;// 獲取當(dāng)前文件的絕對(duì)路徑 console.log(url); console.log(fileURLToPath(url)); console.log(dirname(fileURLToPath(url))); // 獲取文件的絕對(duì)路徑 const path = resolve(dirname(fileURLToPath(url)), "./cuepus/data.json"); console.log(path);
const url = import.meta.url;
:使用了import.meta
對(duì)象來(lái)獲取當(dāng)前模塊文件的絕對(duì) URL 路徑,并將其賦值給變量url
。console.log(fileURLToPath(url));
:將url路徑轉(zhuǎn)換為文件系統(tǒng)路徑console.log(dirname(fileURLToPath(url)));
:將url轉(zhuǎn)換為文件系統(tǒng)路徑,然后通過(guò)dirname
函數(shù)獲取該路徑的目錄部分const path = resolve(dirname(fileURLToPath(url)), "./cuepus/data.json");
:將前面獲取到的目錄部分和相對(duì)路徑"./cuepus/data.json"
進(jìn)行組合,生成一個(gè)完整的文件絕對(duì)路徑,并將其賦值給變量path
。
接下來(lái)我們代碼就可以寫成以下的形式
import fs from "fs"; import { fileURLToPath } from "url"; import { dirname,resolve } from "path"; const url = import.meta.url;// 獲取當(dāng)前文件的絕對(duì)路徑 // 獲取文件的絕對(duì)路徑 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));
接下來(lái)我們寫封裝兩個(gè)函數(shù)
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() // 放棄第一次結(jié)果 return randomPick }
首先,定義了一個(gè)名為 randomInt
的導(dǎo)出函數(shù),它接受兩個(gè)參數(shù) min
和 max
,用于生成指定范圍內(nèi)的隨機(jī)整數(shù)。
然后,定義了一個(gè)名為 createRandomPicker
的導(dǎo)出函數(shù),它接受一個(gè)數(shù)組 arr
作為參數(shù)。
在函數(shù)內(nèi)部,先對(duì)傳入的數(shù)組進(jìn)行了復(fù)制,以避免修改原始數(shù)組。
接著,定義了一個(gè)內(nèi)部函數(shù) randomPick
,它的功能是:
- 計(jì)算數(shù)組的有效長(zhǎng)度。
- 生成一個(gè)在有效范圍內(nèi)的隨機(jī)索引。
- 通過(guò)交換將隨機(jī)索引處的元素與最后一個(gè)元素交換位置。
- 返回交換后的隨機(jī)索引處的元素。
在函數(shù)體中,首先調(diào)用了一次 randomPick
函數(shù),但放棄了這次的結(jié)果。
最后,返回 randomPick
函數(shù),以便外部可以調(diào)用它來(lái)獲取隨機(jī)抽取的數(shù)組元素。
generator.js
import { randomInt, createRandomPicker } from './random.js' // 替換文本 function sentence(pick, replacer) { let ret = pick() // 得到一個(gè)句子 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'
模塊導(dǎo)入了 randomInt
和 createRandomPicker
兩個(gè)函數(shù)。
然后,定義了 sentence
函數(shù),它接受兩個(gè)參數(shù) pick
和 replacer
。
pick
函數(shù)用于獲取一個(gè)句子,然后通過(guò)遍歷 replacer
對(duì)象中的鍵,使用正則表達(dá)式匹配并替換句子中特定的模板字符串(形如 {{key}}
)。如果對(duì)應(yīng)的值是函數(shù),則調(diào)用函數(shù)獲取結(jié)果進(jìn)行替換,否則直接使用值進(jìn)行替換。
接下來(lái),定義了 generate
函數(shù),它接受三個(gè)參數(shù):title
、一個(gè)包含配置信息的對(duì)象(包含 corpus
以及可選的 min
和 max
)。
在函數(shù)內(nèi)部:
- 通過(guò)
randomInt
生成一個(gè)在min
和max
范圍內(nèi)的文章長(zhǎng)度articleLenth
。 - 從
corpus
對(duì)象中解構(gòu)出幾個(gè)部分,并對(duì)每個(gè)部分使用createRandomPicker
函數(shù)創(chuàng)建隨機(jī)選擇器。 - 通過(guò)一個(gè)循環(huán)生成文章內(nèi)容,每次循環(huán)生成一個(gè)段落。在生成段落的過(guò)程中,根據(jù)隨機(jī)數(shù)決定使用不同的句子生成方式,并通過(guò)
sentence
函數(shù)進(jìn)行處理和組合。 - 不斷累加段落的長(zhǎng)度,直到總長(zhǎng)度達(dá)到
articleLenth
,最終將生成的文章段落組成一個(gè)數(shù)組返回。
最后調(diào)用即可,修改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 // 讀取當(dāng)前腳本的絕對(duì)路徑 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(''));
總結(jié)
本文本文將從零開始,講解如何使用Node.js來(lái)實(shí)現(xiàn)一個(gè)文章生成器
希望看到這里的你能夠有所收獲?。。?!自己動(dòng)手實(shí)現(xiàn)一個(gè)簡(jiǎn)易的文章生成器吧
后期可以結(jié)合AI去實(shí)現(xiàn)更加智能的文章生成器
到此這篇關(guān)于使用Node.js實(shí)現(xiàn)一個(gè)文章生成器的文章就介紹到這了,更多相關(guān)Node.js文章生成器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
pnpm實(shí)現(xiàn)依賴包共享和依賴包項(xiàng)目隔離的方法詳解
pnpm是Node.js的包管理器,它是 npm 的直接替代品,相對(duì)于npm和yarn它的優(yōu)點(diǎn)就在于速度快和高效節(jié)省磁盤空間,本文主要講解pnpm相比于npm/yarn如何利用軟硬鏈接來(lái)節(jié)省磁盤空間,以及如何實(shí)現(xiàn)依賴包共享和依賴包項(xiàng)目隔離的,需要的朋友可以參考下2024-05-05Node.JS利用PhantomJs抓取網(wǎng)頁(yè)入門教程
現(xiàn)今,網(wǎng)頁(yè)抓取已經(jīng)是一種人所共知的技術(shù)了,然而依然存在著諸多復(fù)雜性,下面這篇文章主要給大家介紹了Node.JS利用PhantomJs抓取網(wǎng)頁(yè)的方法教程,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-05-05nodejs+express實(shí)現(xiàn)文件上傳下載管理網(wǎng)站
這篇文章主要為大家詳細(xì)介紹了nodejs+express實(shí)現(xiàn)文件上傳下載管理的網(wǎng)站,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03node.js實(shí)現(xiàn)端口轉(zhuǎn)發(fā)
這篇文章主要為大家詳細(xì)介紹了node.js實(shí)現(xiàn)端口轉(zhuǎn)發(fā)的關(guān)鍵代碼,感興趣的小伙伴們可以參考一下2016-04-04使用?Node-RED對(duì)?MQTT?數(shù)據(jù)流處理
本文將介紹使用 Node-RED 連接到 MQTT 服務(wù)器,并對(duì) MQTT 數(shù)據(jù)進(jìn)行過(guò)濾和處理后再將其發(fā)送至 MQTT 服務(wù)器的完整操作流程。讀者可以快速了解如何使用 Node-RED 對(duì) MQTT 數(shù)據(jù)進(jìn)行簡(jiǎn)單的流處理2022-05-05