Universal Text Replacer

通称:スタ置換(Google AI スタジオ強制置換)英名:UTR

目的:予期せぬ出現する、**や(・・・)を削除する
機能:文字列の置換

使用手順:①Tampermonkeyのプラグインを インストール
②「スタ置換」を押して、スクリプトインストールを行う(またはTampermonkeyで、以下のコードを新規保存)
Google Studio AIを起動して置換できるかプレイしてみてね
※Geminiは非対応や、スマホでは動作しません

モバイル版も生成しましたがAndrid版は動作確認できてません
スタ置換foriOS safari+App:UserScript →歯車が出るので保存した瞬間だけ変換する仕様
スタ置換forAndrid FireFox+App:Tampermonkey

うまくいくと以下の様な伏せが自動で置換先の文字に変わる
C
※置換後は自分の目で試してください

・出力のそばから置換する仕組みになってます(リロードすると最後の1ページのみが置換という仕様)
・()を置換と設定しているのは・を先に削除したあとに残るカッコのみを削除する仕組みになってます
・デフォルトで△が未、□が幼となっているのは"非常にはじかれ易い"ので対策しています、そういうことです感じ取ってください。

Tampermonkeyが良く分からない人コチラの下部の解説を参考に

詳しくは下部

// ==UserScript==
// @name         Universal Text Replacer
// @namespace    https://rentry.co/o9ckxybp/
// @version      2.3
// @description  AI Studioの回答を指定したルールで置換する(デフォルト設定強化版)
// @author       ForeverPWA
// @match        *://aistudio.google.com/*
// @match        *://gemini.google.com/* リクエストあれば
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_registerMenuCommand
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // ===== 設定キー =====
    const CONFIG_KEY = 'universal_replacer_config';
    const defaultConfig = {
        rules: [
            { from: '〇', to: '' },
            { from: '△', to: '未' },
            { from: '□', to: '幼' },
            { from: '・', to: '' },
            { from: '()', to: '' },
            { from: '**', to: '' }
        ]
    };

    let config = Object.assign({}, defaultConfig, GM_getValue(CONFIG_KEY, {}));

    // ===== ユーティリティ関数 =====
    function getModelResponseText() {
        const turns = document.querySelectorAll('ms-chat-turn');
        const lastTurn = turns[turns.length - 1];
        if (!lastTurn) return null;
        const container = lastTurn.querySelector('[data-turn-role="Model"]');
        return container;
    }

    // テキスト置換関数
    function applyReplacementRules(text) {
        if (!text) return '';
        let processedText = text;
        config.rules.forEach(rule => {
            if (rule.from) {
                // 特殊文字のエスケープ処理
                const escapedFrom = rule.from.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
                const regex = new RegExp(escapedFrom, 'g');
                // 変換先が空の場合は削除、それ以外は置換
                const replacement = rule.to || '';
                processedText = processedText.replace(regex, replacement);
            }
        });
        return processedText;
    }

    // ===== メインロジック =====
    let debounceTimer = null;
    function handleUpdate() {
        if (debounceTimer) return;
        debounceTimer = setTimeout(() => {
            debounceTimer = null;
            try {
                const container = getModelResponseText();
                if (!container) return;

                const walker = document.createTreeWalker(
                    container,
                    NodeFilter.SHOW_TEXT,
                    null,
                    false
                );

                let node;
                while (node = walker.nextNode()) {
                    let newText = node.nodeValue;
                    let hasChange = false;

                    config.rules.forEach(rule => {
                        if (rule.from && newText.includes(rule.from)) {
                            hasChange = true;
                        }
                    });

                    if (hasChange) {
                        const replaced = applyReplacementRules(node.nodeValue);
                        if (node.nodeValue !== replaced) {
                            node.nodeValue = replaced;
                        }
                    }
                }
            } catch (e) {
                console.warn("Replacer Script: error:", e);
            }
        }, 300);
    }

    // ===== 設定画面 UI (拡大版) =====
    function openSettings() {
        const overlay = document.createElement('div');
        overlay.style.cssText = `position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.7);z-index:10000;display:flex;align-items:center;justify-content:center;`;

        const panel = document.createElement('div');
        panel.style.cssText = `background:#202124;color:#e8eaed;padding:30px;border-radius:12px;width:800px;max-height:85vh;overflow-y:auto;box-shadow: 0 4px 20px rgba(0,0,0,0.5);`;

        const title = document.createElement('h2');
        title.textContent = '置換設定';
        title.style.cssText = 'margin:0 0 25px;font-size:1.8em;color:#f28b82;text-align:center;border-bottom: 2px solid #3c4043;padding-bottom: 10px;';
        panel.appendChild(title);

        const rulesContainer = document.createElement('div');
        rulesContainer.style.marginBottom = '25px';

        function createRuleRow(fromVal, toVal) {
            const row = document.createElement('div');
            row.style.cssText = 'display:flex;gap:15px;margin-bottom:12px;align-items:center;';

            const fromInput = document.createElement('input');
            fromInput.placeholder = '変換元';
            fromInput.value = fromVal;
            fromInput.style.cssText = 'flex:1;padding:12px;background:#3c4043;color:#e8eaed;border:1px solid #5f6368;border-radius:6px;font-size:16px;';

            const arrow = document.createElement('span');
            arrow.textContent = '→';
            arrow.style.cssText = 'font-size:1.2em;color:#9aa0a6;font-weight:bold;';

            const toInput = document.createElement('input');
            toInput.placeholder = '変換先 (空で削除)';
            toInput.value = toVal;
            toInput.style.cssText = 'flex:1;padding:12px;background:#3c4043;color:#e8eaed;border:1px solid #5f6368;border-radius:6px;font-size:16px;';

            const delBtn = document.createElement('button');
            delBtn.textContent = '×';
            delBtn.style.cssText = 'background:transparent;color:#f28b82;border:none;cursor:pointer;font-size:1.5em;padding:0 10px;';
            delBtn.onclick = () => row.remove();

            row.appendChild(fromInput);
            row.appendChild(arrow);
            row.appendChild(toInput);
            row.appendChild(delBtn);
            return row;
        }

        config.rules.forEach(rule => {
            rulesContainer.appendChild(createRuleRow(rule.from, rule.to));
        });
        panel.appendChild(rulesContainer);

        const addBtn = document.createElement('button');
        addBtn.textContent = '+ ルールを追加';
        addBtn.style.cssText = 'width:100%;padding:12px;background:#3c4043;color:#8ab4f8;border:2px dashed #5f6368;border-radius:6px;cursor:pointer;margin-bottom:25px;font-size:16px;';
        addBtn.onclick = () => rulesContainer.appendChild(createRuleRow('', ''));
        panel.appendChild(addBtn);

        const actions = document.createElement('div');
        actions.style.cssText = 'display:flex;justify-content:flex-end;gap:15px;border-top:1px solid #3c4043;padding-top:20px;';

        const cancelBtn = document.createElement('button');
        cancelBtn.textContent = 'キャンセル';
        cancelBtn.style.cssText = 'padding:10px 20px;background:transparent;color:#8ab4f8;border:1px solid #5f6368;border-radius:6px;cursor:pointer;';
        cancelBtn.onclick = () => overlay.remove();

        const saveBtn = document.createElement('button');
        saveBtn.textContent = '保存して適用';
        saveBtn.style.cssText = 'padding:10px 25px;background:#8ab4f8;color:#202124;border:none;border-radius:6px;cursor:pointer;font-weight:bold;';
        saveBtn.onclick = () => {
            const newRules = [];
            Array.from(rulesContainer.children).forEach(row => {
                const inputs = row.querySelectorAll('input');
                if (inputs[0].value) {
                    newRules.push({ from: inputs[0].value, to: inputs[1].value });
                }
            });
            config.rules = newRules;
            GM_setValue(CONFIG_KEY, config);
            handleUpdate();
            overlay.remove();
        };

        actions.appendChild(cancelBtn);
        actions.appendChild(saveBtn);
        panel.appendChild(actions);
        overlay.appendChild(panel);
        document.body.appendChild(overlay);
    }

    // ===== 初期化 =====
    GM_registerMenuCommand('置換設定', openSettings);

    const observer = new MutationObserver(handleUpdate);
    observer.observe(document.body, { childList: true, subtree: true });
    setTimeout(handleUpdate, 2000);

})();

使い方例)
〇を伏字ではなく う〇ん〇ち はさみ伏字に使います
はさみ伏字が効かない強力なのは△□で対応します

これでコンテンツブロックする確率は0%になると思います ※すみません、ハルシネーションでした
日本語推論プレイヤーの方は、内部推論プロセスも伏せさせたり、そもそも推論なしとかで調整します
↓以下ならコンテンツブロック0%あると思います!!

その他のプロンプト

URL自動デコード(当ツールの上位互換)

https://rentry.co/3hb6piip

日本語推論ちゃん<J>:最終版

https://rentry.org/wxt5qv2b

推論応用編(プレイ目的ではなく応用プロンプト)

親戚家族の夜の営みを目撃したケンの記録:リメイク版
https://rentry.co/suomd38y

その他のツール

Google AI Studio に直接画像を出したい!

通称:MIR(スタ画)
https://rentry.co/3bnuvgwu

Wikiのプロンプトまとめ等をみながら、プロンプトだけを即コピーしたい人用に作成しました

通称:即コピ
https://rentry.co/8772bcnh

Google AI Studioで自動で読み上げ(VOICEVOX)させたい

通称:スタ自ボ
https://rentry.co/x9fw82o3/edit

Edit

Pub: 29 Nov 2025 04:32 UTC

Edit: 12 Dec 2025 15:29 UTC

Views: 974