注意: 保存した後、ブラウザのキャッシュをクリアする必要があります。Mozilla / Firefox / Safari: [Shift] を押しながら [再読み込み] をクリック、または [Shift]-[Ctrl]-[R] (Macでは [Cmd]-[Shift]-[R]); IE: [Ctrl] を押しながら [更新] をクリック、または [Ctrl]-[F5]; Konqueror: [再読み込み] をクリック、または [F5]; Opera: 「ツール」→「設定」からキャッシュをクリア。

// 置換パターンと置換処理の配列
const replacements = [
    // nowikiタグやエスケープ文字に関する置換処理
    {
        // nowikiタグや特定のエスケープ文字にマッチするパターン
        pattern: /(?:<nowiki((?: .*?)*?)>(.*?)<\/nowiki>|\{\\((?: .*?)*?\|)?(.*?)\\\})/gs,
        // 置換処理: エスケープする文字をHTMLエンティティに変換
        replacement: (match, attribute1, content1, attribute2, content2) => {
            // エスケープすべき文字のリストとその対応するHTMLエンティティ
            const references = {
                '<': '&lt;',
                '>': '&gt;',
                ' ': '&nbsp;',
                '/': '&#47;',
                '\\': '&#92;',
                '&': '&amp;',
                "'": '&apos;',
                '"': '&quot;',
                '`': '&#96;',
                '|': '&verbar;',
                '!': '&excl;',
                '[': '&lbrack;',
                ']': '&rbrack;',
                '{': '&lbrace;',
                '}': '&rbrace;',
                '=': '&equals;',
                '+': '&plus;',
                '-': '&minus;',
                '*': '&ast;',
                '#': '&#35;',
                ':': '&colon;',
                ';': '&semi;',
                '~': '&#126;',
                // 他のエスケープ文字を追加
            };
            // content1またはcontent2のどちらかを使ってエスケープ処理を行う
            const content = content1 || content2;
            // content内の該当文字をreferencesに基づいてエスケープ
            const escapedContent = content.replace(/[<> \/\\\&'"`\|\!\|\[\]\{\}=\+\-\*\#\:\;~]/g, char => references[char]);
            // 属性を持つspanタグでエスケープされた内容を囲む
            return `<span${attribute1 || attribute2}>${escapedContent}</span>`;
        }
    },
    // 番号付きリスト(任意の番号から始まるリスト)の変換処理(まだ使えません)
    /*
     * {
     *     // 番号付きリストや箇条書きの記号にマッチするパターン
     *     pattern: /^((?:[\*・\#;:]|\d+\.|[⓪①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳㉑㉒㉓㉔㉕㉖㉗㉘㉙㉚㉛㉜㉝㉞㉟㊱㊲㊳㊴㊵㊶㊷㊸㊹㊺㊻㊼㊽㊾㊿🄋➀➁➂➃➄➅➆➇➈➉⓿❶❷❸❹❺❻❼❽❾❿⓫⓬⓭⓮⓯⓰⓱⓲⓳⓴🄌➊➋➌➍➎➏➐➑➒➓⓵⓶⓷⓸⓹⓺⓻⓼⓽⓾])+)(.*)$/gm,
     *     // 置換処理: 記号を#に置き換える
     *     replacement: (match, symbols, content) => {
     *         // リストの記号を#に置き換える
     *         const newSymbols = symbols.replace(/(?:\d+\.|[⓪①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳㉑㉒㉓㉔㉕㉖㉗㉘㉙㉚㉛㉜㉝㉞㉟㊱㊲㊳㊴㊵㊶㊷㊸㊹㊺㊻㊼㊽㊾㊿🄋➀➁➂➃➄➅➆➇➈➉⓿❶❷❸❹❺❻❼❽❾❿⓫⓬⓭⓮⓯⓰⓱⓲⓳⓴🄌➊➋➌➍➎➏➐➑➒➓⓵⓶⓷⓸⓹⓺⓻⓼⓽⓾])/g, `#`);
     *         // 置換後の記号と内容を結合して返す
     *         return newSymbols + content.trim();
     *     }
     * },
     */
    // 箇条書きリストの変換処理
    /*
     * {
     *     // 箇条書きの記号にマッチするパターン
     *     pattern: /^((?:[\*・\#;:]|\d+\.|[⓪①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳㉑㉒㉓㉔㉕㉖㉗㉘㉙㉚㉛㉜㉝㉞㉟㊱㊲㊳㊴㊵㊶㊷㊸㊹㊺㊻㊼㊽㊾㊿🄋➀➁➂➃➄➅➆➇➈➉⓿❶❷❸❹❺❻❼❽❾❿⓫⓬⓭⓮⓯⓰⓱⓲⓳⓴🄌➊➋➌➍➎➏➐➑➒➓⓵⓶⓷⓸⓹⓺⓻⓼⓽⓾])+)(.*)$/gm,
     *     // 置換処理: リストの記号を*に置き換える
     *     replacement: (match, symbols, content) => {
     *         // ・を*に置き換える
     *         const newSymbols = symbols.replace(/・/g, `*`);
     *         // 置換後の記号と内容を結合して返す
     *         return newSymbols + content.trim();
     *     }
     * },
     */
    // コードブロックをHTMLの<code>タグで囲む処理
    {
        // インラインコードにマッチするパターン
        pattern: /`(.*?)`/g,
        // 置換処理: <code>タグで内容を囲む
        replacement: (match, content) => {
            return `<code>${content}</code>`;
        }
    },
    // 利用者ページで使う新規作成リストの簡潔化
    /*
     * {{特別:投稿記録
	 * | target    = {{BASEPAGENAME}} <!-- 投稿者名。ここでは利用者ページの名前空間とサブページを除外している。 -->
	 * | namespace = 0 <!-- 名前空間。`0`は記事名前空間であることを示す。 -->
	 * | tagfilter = mw-new-redirect <!-- 新規リダイレクトの作成を指定する。 -->
	 * | tagInvert = 1 <!-- 上記で指定したタグを除外する。 -->
	 * | newOnly   = 1 <!-- ページの新規作成に限定する。 -->
	 * | start     = <!-- リストの開始日時 -->
	 * | end       = <!-- リストの終了日時 -->
	 * | limit     = <!-- 表示する最大項目数 -->
	 * }}
	 */
    {
        // <section>タグで囲まれた部分を対象にする正規表現パターン
        pattern: /(<section class="mw\-pager\-body">)(.*?)(<\/section>)/gs,
        // パターンに一致した部分を置換する処理
        replacement: (match, openingSectionTag, section, closingSectionTag) => {
            // <h4>と、<ul>タグで囲まれたリストをさらに処理
            const newSection = section.replace(
                /<h4 class="(?:mw\-index\-pager\-list\-header\-first )?mw\-index\-pager\-list\-header">(.*?)<\/h4>(<ul class="mw\-contributions\-list">)(.*?)(<\/ul>)/gs,
                (match, h4Content, openingUlTag, listItem, closingUlTag) => {
                    // <li>タグ内の特定の情報を抽出し、スタイルを追加
                    const newListItem = listItem.replace(
                        /<(li data\-mw\-revid="\d+"(?: class=".*?")?)><span class="mw\-changeslist\-time">(\d{2}\:\d{2})<\/span>(<a href=".*?\/w\/index\.php\?title=.*?&amp;oldid=\d+" class="mw\-changeslist\-date" title=".*?">)(.*?)(<\/a>).*?(<a href="\/(?:Wiki\/Wikifoods\/w\/index\.php|wiki)\/.*?" class="mw\-contributions\-title" title=".*?">.*?<\/a>).*?(<\/li>)/gs,
                        // スタイル属性を追加して、新しい<li>要素を生成
                        (match, openingLiTag, timestamp, openingATag, dateAndTimestamp, closingATag, pagetitle, closingLiTag) => {
                            return '<' + openingLiTag + 'style="min-height: 0;">' + '<h5 style="display: inline;" id="' + dateAndTimestamp + '"></h5>' + openingATag + timestamp + closingATag + ' ' + pagetitle + closingLiTag;
                        }
                    );
                    // 置換された<ul>を返す
                    return '<li><h4 id="' + h4Content + '">' + h4Content + '</h4>' + openingUlTag + newListItem + closingUlTag + '</li>';
                }
            );
            // 置換された<section>を返す
            return openingSectionTag + '<ul>' + newSection + '</ul>' + closingSectionTag;
        }
    },
];

// 特定のIDを持つ子要素を除外して置換を行う関数
function performReplacementsExcludingChild(parentElement, childIdToExclude, replacements) {
    // 子要素を検索して、IDが一致するものを取得
    const childToExclude = parentElement.querySelector(`#${childIdToExclude}`);
    
    // 子要素が存在する場合は、一時的にその子要素を取り除く
    if (childToExclude) {
        childToExclude.parentElement.removeChild(childToExclude);
    }

    // 親要素のテキストに対して置換を実行
    let text = parentElement.innerHTML;
    replacements.forEach(replacement => {
        text = text.replace(replacement.pattern, replacement.replacement);
    });

    // 置換後のテキストを親要素に再設定
    parentElement.innerHTML = text;

    // 子要素を再度追加
    if (childToExclude) {
        parentElement.appendChild(childToExclude);
    }
}

// 置換を行う元のテキストを取得
const contentWiki = document.getElementsByClassName('mw-content-ltr')[0]; // wiki要素を取得(最初のwiki要素を対象とする場合)
const childIdToExclude = 'wpTextbox1'; // 除外したい子要素のID

// 置換を実行する
performReplacementsExcludingChild(contentWiki, childIdToExclude, replacements);