persianprobeپروب فارسی
GitHubگیت‌هاب

for developers and AI coding agentsبرای برنامه‌نویس‌ها و ایجنت‌های کدنویسی · v0.1.0

Persian text behaves differently in every language.متن فارسی در هر زبان جور دیگری رفتار می‌کند.

int("۱۲۳") works in Python and is NaN in JavaScript; \d does not match ۵; Go counts bytes; a default sort puts پ after ت. persianprobe runs the same 14 probes through every runtime on your machine (Python, Node, Bun, Perl, SQLite, jq, Go, awk), prints one table of what each returns against what a Persian-speaking user expects, and tells you where they disagree and how to fix it.int("۱۲۳") در پایتون کار می‌کند و در جاوااسکریپت NaN است؛ \d عدد ۵ را نمی‌گیرد؛ Go بایت می‌شمارد؛ sort پیش‌فرض «پ» را بعد از «ت» می‌گذارد. persianprobe همان ۱۴ پروب را روی همهٔ runtimeهای دستگاه شما (Python، Node، Bun، Perl، SQLite، jq، Go، awk) اجرا می‌کند، یک جدول از آنچه هرکدام برمی‌گرداند در برابر انتظار کاربر فارسی‌زبان می‌دهد و می‌گوید کجا اختلاف دارند و چطور درست شود.

  • Python
  • MIT
  • 0 deps
  • v0.1.0
xrayruns in your browser · nothing is sentدر مرورگر شما اجرا می‌شود · چیزی ارسال نمی‌شود

    Same idea as persianprobe xray. Move the pointer over the glyph storm to read code points.همان ایدهٔ persianprobe xray. نشانگر را روی طوفان نویسه‌ها ببرید تا کد نویسه‌ها را ببینید.

    The problemمسئله

    Does your language handle Persian text the way you think it does? persianprobe runs 14 probes through 8 runtimes.زبان برنامه‌نویسی‌تان متن فارسی را همان‌طور که فکر می‌کنید پردازش می‌کند؟ persianprobe چهارده پروب را روی هشت runtime اجرا می‌کند.

    The problemمسئله

    Persian text breaks software quietly. int("۱۲۳") is 123 in Python and NaN in JavaScript; SQLite CAST returns 0 without a word; \d does not match ۵ in most engines; a default sort puts پ after ت; Go len returns bytes; a user types علي with an Arabic yeh and your unique index now has two "علی". AI assistants write the English-shaped version of the code.متن فارسی نرم‌افزار را بی‌صدا می‌شکند. int("۱۲۳") در پایتون ۱۲۳ است و در جاوااسکریپت NaN؛ CAST در SQLite بدون هیچ پیامی ۰ برمی‌گرداند؛ \d در بیشتر موتورها ۵ را نمی‌گیرد؛ sort پیش‌فرض «پ» را بعد از «ت» می‌گذارد؛ len در Go بایت می‌شمارد؛ کاربر «علي» را با ی عربی می‌نویسد و ایندکس یکتای شما حالا دو «علی» دارد. دستیارهای هوش مصنوعی نسخهٔ انگلیسی‌شکل کد را می‌نویسند.

    What it doesچه می‌کند

    It runs the same 14 probes (parse ۱۲۳, does \d match ۵, length of نامه‌ها, is علی equal to علي, how sort orders ا ب پ ت, how JSON writes سلام, NFKC, Jalali dates, fa-IR number format) through every runtime installed on your machine (Python, Node, Bun, Perl, SQLite, jq, Go, awk) using the idiom a developer would naturally write. One table shows what each returns, what a Persian-speaking user expects, and the verdict: portability traps, nothing gets it right, or capability gaps, each with a fix per runtime. A helper, persianprobe xray, lists look-alike and invisible characters in a text.همان ۱۴ پروب (تبدیل ۱۲۳ فارسی، آیا \d عدد ۵ را می‌گیرد، طول «نامه‌ها»، برابری «علی» و «علي»، ترتیب sort برای ا ب پ ت، نوشتن «سلام» در JSON، NFKC، تاریخ جلالی، قالب اعداد fa-IR) را روی هر runtimeی که روی دستگاه شما نصب است (Python، Node، Bun، Perl، SQLite، jq، Go، awk) با همان روشی که برنامه‌نویس طبیعی می‌نویسد اجرا می‌کند. یک جدول نشان می‌دهد هرکدام چه برمی‌گرداند، کاربر فارسی‌زبان چه انتظاری دارد و حکم چیست: تله‌های سازگاری، چیزی که هیچ‌کس درست نمی‌دهد یا شکاف قابلیت، هرکدام با راه‌حل برای هر runtime. ابزار کمکی persianprobe xray نویسه‌های شبیه‌هم و نامرئی یک متن را فهرست می‌کند.

    • 14۱۴probes: digits, regex, length, sort, JSON, Jalali…پروب: ارقام، regex، طول، مرتب‌سازی، JSON، جلالی…
    • 8۸runtimes: Python, Node, Bun, Perl, SQLite, jq, Go, awkruntime: Python، Node، Bun، Perl، SQLite، jq، Go، awk
    • 25۲۵tests · 0 dependenciesآزمون · بدون وابستگی

    Demoنمایش

    Real output from eight real runtimesخروجی واقعی از هشت runtime واقعی

    Pick a view. This is the unedited output of persianprobe on the development machine (docs/demo.txt): Python 3.13, Node 20, Bun 1.4, Perl 5.40, SQLite 3.46, jq 1.7, Go 1.27 and mawk, with LC_ALL=C.UTF-8. Your versions may answer differently, which is the point of running it. Persian digits are shown in an ASCII view so the table stays aligned.یک نما را انتخاب کنید. این خروجی ویرایش‌نشدهٔ persianprobe روی دستگاه توسعه است (docs/demo.txt): Python 3.13، Node 20، Bun 1.4، Perl 5.40، SQLite 3.46، jq 1.7، Go 1.27 و mawk با LC_ALL=C.UTF-8. نسخه‌های شما ممکن است جور دیگری جواب بدهند، و همین دلیل اجرای آن است. ارقام فارسی در نمای ASCII نشان داده شده‌اند تا جدول تراز بماند.

    $ persianprobepersianprobe

    Full unedited output of the demoخروجی کامل و ویرایش‌نشدهٔ نمایش
    persianprobe 0.1.0 · LC_ALL=C.UTF-8
      python  Python 3.13.5
      node    v20.19.2
      bun     bun 1.4.2
      perl    v5.40.1
      sqlite  SQLite 3.46.1
      jq      jq-1.7
      go      go version go1.27.3 linux/amd64
      awk     mawk 1.3.4 20250131
    
    probe               expected          python            node                 bun                  perl              sqlite            jq                go                awk       
    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    parse-int           123               123 ✓             NaN ✗                NaN ✗                0 ✗               0 ✗               error ✗           error ✗           0 ✗
    parse-int-sep       1234              error ✗           NaN ✗                NaN ✗                0 ✗               0 ✗               error ✗           error ✗           0 ✗
    parse-float-dot     1.5               1.5 ✓             NaN ✗                NaN ✗                0 ✗               0.0 ✗             error ✗           error ✗           0 ✗
    parse-float-fa-sep  1.5               error ✗           NaN ✗                NaN ✗                0 ✗               0.0 ✗             error ✗           error ✗           0 ✗
    digit-regex         true              true ✓            false ✗              false ✗              true ✓            false ✗           true ✓            false ✗           false ✗
    word-regex          true              true ✓            false ✗              false ✗              true ✓            -                 true ✓            false ✗           -
    length              7                 7 ✓               7 ✓                  7 ✓                  7 ✓               7 ✓               7 ✓               15 ✗              15 ✗
    equal-ye            true              false ✗           false ✗              false ✗              false ✗           false ✗           false ✗           false ✗           false ✗
    sort-default        alef be pe te     alef be te pe ✗   alef be te pe ✗      alef be te pe ✗      alef be te pe ✗   alef be te pe ✗   alef be te pe ✗   alef be te pe ✗   -
    sort-fa-locale      alef be pe te     -                 alef be pe te ✓      alef be pe te ✓      alef be pe te ✓   -                 -                 -                 -
    json-encode         raw UTF-8         \u escapes ✗      raw UTF-8 ✓          raw UTF-8 ✓          raw UTF-8 ✓       raw UTF-8 ✓       raw UTF-8 ✓       raw UTF-8 ✓       -
    nfkc                U+0644 U+0627     U+0644 U+0627 ✓   U+0644 U+0627 ✓      U+0644 U+0627 ✓      U+0644 U+0627 ✓   -                 -                 -                 -
    jalali-format       1405/8/2 (fa)     -                 1405/8/2 (fa) ✓      1405/8/2 (fa) ✓      -                 -                 -                 -                 -
    number-format-fa    1,234,567.5 (fa)  -                 1,234,567.5 (fa) ✓   1,234,567.5 (fa) ✓   -                 -                 -                 -                 -
    
    ✓ matches what a Persian-speaking user expects · ✗ does not · - not available in that runtime
    
    14 probes · 6 portability traps (runtimes disagree) · 4 that no runtime gets right · 4 fine where available
    
    PORTABILITY TRAPS: the same code gives different answers [6]
    
    ✗ parse-int · parse the integer ۱۲۳ (Persian digits)
        right:  python
        wrong:  node, bun, perl, sqlite, jq, go, awk
        why:    Only Python's int() accepts non-ASCII digits. Everything else returns NaN/0/error, silently in JS, Perl, SQLite and awk.
        fix:    [node] const toEn = s => s.replace(/[۰-۹]/g, d => d.charCodeAt(0) - 1776).replace(/[٠-٩]/g, d => d.charCodeAt(0) - 1632);
                toEn("۱۲۳") // "123"
                [bun] same as node: map ۰-۹ (U+06F0..) and ٠-٩ (U+0660..) to ASCII before parseInt
                [perl] tr/۰-۹٠-٩/0-90-9/ on the string before numeric use
                [sqlite] do it in the application: SQLite CAST stops at the first non-ASCII character and returns 0 without an error
                [jq] explode | map(if . >= 1776 and . <= 1785 then . - 1728 else . end) | implode | tonumber
                [go] strings.Map(func(r rune) rune { if r >= 0x06F0 && r <= 0x06F9 { return r - 0x06F0 + '0' }; return r }, s)
                [awk] convert in the shell first, e.g. sed 'y/۰۱۲۳۴۵۶۷۸۹/0123456789/'
    
    ✗ parse-float-dot · parse ۱.۵ (Persian digits, ASCII dot)
        right:  python
        wrong:  node, bun, perl, sqlite, jq, go, awk
        why:    Python accepts it, JavaScript returns NaN, Perl/SQLite/awk return 0.
        fix:    [all] map the digits to ASCII first
    
    ✗ digit-regex · does the regex \d match the digit ۵?
        right:  python, perl, jq
        wrong:  node, bun, sqlite, go, awk
        why:    Python, Perl and jq (Unicode-aware \d) say yes; JavaScript, Go, SQLite GLOB and awk say no. The same validation regex gives different answers per language.
        fix:    [node, bun] /[\d۰-۹٠-٩]/ or /\p{Nd}/u
                [sqlite] GLOB has no Unicode classes: validate in the application
                [go] regexp.MustCompile(`\p{Nd}`)
                [awk] awk cannot do this portably: normalise digits first
    
    ✗ word-regex · does the regex \w match the letter ک?
        right:  python, perl, jq
        wrong:  node, bun, go
        why:    JavaScript and Go define \w as [A-Za-z0-9_], so a Persian word is not a 'word'. Python, Perl and jq are Unicode-aware.
        fix:    [node, bun] /[\p{L}\p{N}_]/u
                [go] regexp.MustCompile(`[\p{L}\p{N}_]`)
    
    ✗ length · length of نامه‌ها (6 letters + 1 ZWNJ = 7 characters)
        right:  python, node, bun, perl, sqlite, jq
        wrong:  go, awk
        why:    Go's len() and awk (without multibyte support) count UTF-8 bytes: 15 instead of 7.
        fix:    [go] utf8.RuneCountInString(s)
                [awk] use gawk in a UTF-8 locale, or do the length check in another tool
    
    ✗ json-encode · JSON-encode the string سلام
        right:  node, bun, perl, sqlite, jq, go
        wrong:  python
        why:    Python's json.dumps escapes everything to \u0633\u0644...: valid JSON, but unreadable in logs, diffs and databases, and different bytes from every other runtime.
        fix:    [python] json.dumps(obj, ensure_ascii=False)
    
    NO RUNTIME GETS IT RIGHT: you must handle it yourself [4]
    
    ✗ parse-int-sep · parse ۱٬۲۳۴ (Persian thousands separator U+066C)
        wrong:  python, node, bun, perl, sqlite, jq, go, awk
        why:    Even Python fails once the separator ٬ (U+066C) is present, which is exactly what Intl/fa-IR formatting produces.
        fix:    [all] strip ٬ (U+066C) and ، and replace ٫ (U+066B) with '.', then map the digits; do it before parsing
    
    ✗ parse-float-fa-sep · parse ۱٫۵ (Persian decimal separator U+066B)
        wrong:  python, node, bun, perl, sqlite, jq, go, awk
        why:    No standard library understands ٫ (U+066B) as a decimal point.
        fix:    [all] replace ٫ with '.' and ٬ with '' after mapping digits
    
    ✗ equal-ye · is علی (Persian ی U+06CC) equal to علي (Arabic ي U+064A)?
        wrong:  python, node, bun, perl, sqlite, jq, go, awk
        why:    Every runtime says they differ. Search, login names and unique keys silently split in two unless you fold Arabic ي ى ك to ی ک at input.
        fix:    [python] s.translate({0x064A: "ی", 0x0649: "ی", 0x0643: "ک"})
                [node, bun] s.replace(/[يى]/g, "ی").replace(/ك/g, "ک")
                [perl, jq, go, awk] fold ي (U+064A) and ى (U+0649) to ی (U+06CC), ك (U+0643) to ک (U+06A9) before storing and before comparing
                [sqlite] REPLACE(REPLACE(REPLACE(x, 'ي', 'ی'), 'ى', 'ی'), 'ك', 'ک') in a generated column or trigger
    
    ✗ sort-default · sort the letters ت پ ب ا with the default sort
        wrong:  python, node, bun, perl, sqlite, jq, go
        why:    Every default sort is by code point. پ چ ژ گ are encoded after the Arabic letters, so پ lands after ت instead of between ب and ت.
        fix:    [python] PyICU Collator.createInstance(Locale('fa')), or a key function built from the Persian alphabet order
                [node, bun] l.sort(new Intl.Collator("fa").compare)
                [perl] Unicode::Collate::Locale->new(locale => "fa")->sort(@l)
                [sqlite] load the ICU extension and use COLLATE, or sort in the application with a Persian collator
                [jq] use a Persian collator (ICU 'fa'), never the default sort
                [go] golang.org/x/text/collate with language.Persian
    
    CAPABILITY GAPS: fine where it exists, missing elsewhere
    
    · sort-fa-locale: not built in for python
    

    Featuresامکانات

    What it does, precisely.دقیقاً چه می‌کند.

    01

    One matrix, eight runtimesیک ماتریس، هشت runtime

    Runs real interpreters installed on your machine, not a table copied from a blog. A probe a runtime cannot do prints n/a and is not counted as a disagreement.مفسرهای واقعی نصب‌شده روی دستگاه شما را اجرا می‌کند، نه جدولی کپی‌شده از یک وبلاگ. پروبی که یک runtime نتواند انجام دهد n/a چاپ می‌شود و اختلاف حساب نمی‌شود.

    02

    Three kinds of verdictسه نوع حکم

    Portability traps (some runtimes are right, some wrong), nothing gets it right (you must handle it yourself), and capability gaps (only some runtimes have it at all).تله‌های سازگاری (بعضی runtimeها درست و بعضی غلط‌اند)، هیچ‌کس درست نمی‌دهد (خودتان باید مدیریت کنید) و شکاف قابلیت (فقط بعضی runtimeها اصلاً دارندش).

    03

    A fix per runtimeراه‌حل برای هر runtime

    For every trap it prints the snippet for node, bun, perl, sqlite, jq, go or awk: map ۰-۹ and ٠-٩ to ASCII before parsing, use localeCompare("fa") to sort, and so on.برای هر تله قطعهٔ کد node، bun، perl، sqlite، jq، go یا awk را چاپ می‌کند: نگاشت ۰-۹ و ٠-٩ به ASCII پیش از تبدیل، استفاده از localeCompare("fa") برای مرتب‌سازی و مانند آن.

    04

    xray: look-alike charactersxray: نویسه‌های شبیه‌هم

    persianprobe xray TEXT lists, with positions and code points, Arabic ي ى ك, Arabic-Indic digits, tatweel, PDF presentation forms, invisible bidi marks, BOM and mixed digit systems; --fix prints a normalized copy.دستور persianprobe xray TEXT با جایگاه و کد یونیکد فهرست می‌کند: ي ى ك عربی، ارقام عربی-هندی، کشیده، شکل‌های ارائه از PDF، نشانه‌های نامرئی جهت، BOM و ترکیب دستگاه‌های ارقام؛ --fix نسخهٔ نرمال‌شده را چاپ می‌کند.

    05

    Honest about "expected"صادق دربارهٔ «انتظار»

    "Expected" is what a Persian-speaking user usually expects, which is a judgement. equal-ye being false is correct Unicode, and it is listed because it surprises users and splits data. Read the why before you act.«انتظار» همان چیزی است که کاربر فارسی‌زبان معمولاً انتظار دارد، یعنی یک قضاوت. نابرابری equal-ye از نظر یونیکد درست است و چون کاربران را غافلگیر می‌کند و داده را دو تکه می‌کند فهرست شده. پیش از اقدام «why» را بخوانید.

    06

    CI gate and agentsگیت CI و ایجنت‌ها

    --json for machines, --strict exits 1 on any trap, and a snippet for AGENTS.md / CLAUDE.md so an assistant checks Persian behaviour before it writes an English-shaped validator or sort.‎--json برای ماشین، ‎--strict با هر تله با کد ۱ خارج می‌شود و یک snippet برای AGENTS.md / CLAUDE.md تا دستیار پیش از نوشتن اعتبارسنج یا sort انگلیسی‌شکل رفتار فارسی را بررسی کند.

    • Python
    • Unicode
    • Node
    • SQLite
    • Go
    • xray

    Install & quick startنصب و شروع سریع

    Up and running in a minute.در یک دقیقه راه بیندازید.

    1. Install (Python 3.9+, other runtimes optional)نصب (پایتون ۳٫۹ به بالا، بقیهٔ runtimeها اختیاری)

      pipx install git+https://github.com/mrzroot/persianprobe
      # or run without installing:
      uvx --from git+https://github.com/mrzroot/persianprobe persianprobe
    2. Run the probesاجرای پروب‌ها

      persianprobe                                  # all probes, all runtimes found
      persianprobe --runtimes python,node,sqlite    # only these
      persianprobe --probes parse-int,sort-default  # only these probes
      persianprobe --list                           # the idiom used per runtime
    3. X-ray a text, or use it as a gateکالبدشکافی متن، یا استفاده به‌عنوان گیت

      persianprobe xray "علي  كتاب‌ها ٤٥٦"
      persianprobe xray -f pasted.txt --fix --digits en
      persianprobe --strict   # exit 1 if any probe is a trap (CI)

    How it worksچطور کار می‌کند

    Four steps, no magic.چهار گام، بدون جادو.

    Real interpreters, natural idiomsمفسرهای واقعی، روش طبیعی

    Each probe runs through a subprocess of the runtime with the idiom a developer would naturally write (parseInt(s), int(s), /\d/, len(s), ORDER BY), not a workaround. persianprobe --list shows the exact code per runtime.هر پروب در یک زیرفرایند همان runtime با روشی اجرا می‌شود که برنامه‌نویس طبیعی می‌نویسد (‏parseInt(s)، ‏int(s)، ‏/\d/، ‏len(s)، ‏ORDER BY)، نه راه‌حل دورزنی. ‎persianprobe --list‎ کد دقیق هر runtime را نشان می‌دهد.

    Compare with what users expectمقایسه با انتظار کاربر

    Every probe has an expected value (123 for ۱۲۳, true for \d on ۵). A runtime that cannot do the probe prints n/a and is not counted as a disagreement.هر پروب یک مقدار مورد انتظار دارد (۱۲۳ برای «۱۲۳»، true برای \d روی ۵). runtimeای که پروب را نتواند انجام دهد n/a چاپ می‌کند و اختلاف حساب نمی‌شود.

    Sort into verdictsدسته‌بندی در حکم‌ها

    Portability traps (some runtimes are right, some wrong), no runtime gets it right, and capability gaps. Each trap lists the right and wrong runtimes, why, and a fix snippet per runtime.تله‌های سازگاری (بعضی درست، بعضی غلط)، هیچ runtime درست نمی‌دهد و شکاف قابلیت. هر تله runtimeهای درست و غلط، دلیل و قطعهٔ راه‌حل برای هر runtime را فهرست می‌کند.

    xray any textکالبدشکافی هر متن

    persianprobe xray lists look-alike characters with positions and code points (Arabic yeh and kaf, Arabic-Indic digits, tatweel, presentation forms, invisible marks); --fix prints a normalized copy. The same function is a library: from persianprobe.xray import normalize.دستور persianprobe xray نویسه‌های شبیه‌هم را با جایگاه و کد یونیکد فهرست می‌کند (ی و ک عربی، ارقام عربی-هندی، کشیده، شکل‌های ارائه، نشانه‌های نامرئی)؛ ‎--fix‎ نسخهٔ نرمال‌شده را چاپ می‌کند. همین تابع یک کتابخانه است: ‎from persianprobe.xray import normalize‎.

    Honest limitsمحدودیت‌های صادقانه

    What it does not do. Please read.چه کارهایی نمی‌کند. لطفاً بخوانید.

    • "Expected" is what a Persian-speaking user usually expects, which is a judgement. equal-ye being false is correct Unicode and json-encode is a style preference more than a bug. Read the why before acting.«انتظار» همان چیزی است که کاربر فارسی‌زبان معمولاً انتظار دارد، یعنی یک قضاوت. نابرابری equal-ye از نظر یونیکد درست است و json-encode بیشتر سلیقه است تا باگ. پیش از اقدام «why» را بخوانید.
    • It reports what the interpreters installed on this machine do, with LC_ALL=C.UTF-8 by default (Python runs with -X utf8). Other versions, locales or ICU builds can differ; use --locale and rerun.گزارش می‌دهد مفسرهای نصب‌شده روی همین دستگاه چه می‌کنند، با LC_ALL=C.UTF-8 به‌صورت پیش‌فرض (پایتون با -X utf8). نسخه، locale یا ICU دیگر می‌تواند فرق کند؛ با --locale دوباره اجرا کنید.
    • Ruby and PHP adapters are not provided (they were not available on the development machine, so they could not be tested). Adapters for more runtimes are welcome.آداپتر Ruby و PHP ندارد (روی دستگاه توسعه نبودند و آزمون نشدند). آداپتر برای runtimeهای بیشتر خوشامد است.
    • sort-fa-locale for Python needs an OS fa_IR.UTF-8 locale, which most systems lack, so it shows -. Tested on Linux only; Windows and macOS are untested.sort-fa-locale برای پایتون به locale ‏fa_IR.UTF-8 سیستم‌عامل نیاز دارد که بیشتر سیستم‌ها ندارند و «-» نشان می‌دهد. فقط روی لینوکس آزموده شده؛ ویندوز و macOS آزموده نشده‌اند.

    How it comparesمقایسه با ابزارهای دیگر

    Closest things, and the difference.نزدیک‌ترین‌ها و تفاوت‌شان.

    No existing tool found as of Oct 2026تا مهر ۱۴۰۵ (اکتبر ۲۰۲۶) ابزار مشابهی پیدا نشد that runs one set of Persian-text probes through many real runtimes on your machine and compares them with what users expect.که یک مجموعه پروب متن فارسی را روی چند runtime واقعی دستگاه شما اجرا کند و با انتظار کاربر مقایسه کند.

    This is the outcome of searches of GitHub, npm, PyPI and the web on 24 Oct 2026, not a guarantee: search indexes are incomplete and this space changes weekly. If you know one, please open an issue and it will be linked here.این نتیجهٔ جست‌وجو در گیت‌هاب، npm، PyPI و وب در ۲ آبان ۱۴۰۵ است، نه تضمین: نمایه‌های جست‌وجو ناقص‌اند و این حوزه هر هفته عوض می‌شود. اگر موردی می‌شناسید لطفاً یک issue باز کنید تا اینجا پیوند شود.

    ToolابزارWhat it doesچه می‌کندHow it differsتفاوت
    persian-normalizeA library that normalizes Persian text for one language (JavaScript)کتابخانه‌ای که متن فارسی را برای یک زبان (جاوااسکریپت) نرمال می‌کندFixes text inside one language; it does not show how eight runtimes disagree on the same inputمتن را داخل یک زبان درست می‌کند؛ نشان نمی‌دهد هشت runtime روی یک ورودی چقدر اختلاف دارند
    hazm, parsivarPersian NLP toolkits for Pythonجعبه‌ابزار پردازش زبان فارسی برای پایتونNLP inside Python; persianprobe is about what your runtime does to Persian text by defaultپردازش زبان داخل پایتون؛ persianprobe دربارهٔ کاری است که runtime شما به‌طور پیش‌فرض با متن فارسی می‌کند
    perso-matchPersian and Arabic search normalization with highlight rangesنرمال‌سازی جست‌وجوی فارسی و عربی با بازهٔ هایلایتA search library, not a cross-runtime comparisonکتابخانهٔ جست‌وجو است، نه مقایسهٔ چند runtime
    paksaz, persian-tabular-cleanerClean Persian CSV and Excel dataپاک‌سازی داده‌های CSV و اکسل فارسیData cleaners for files; they do not probe how your code and database treat Persian textپاک‌سازهای فایل‌اند؛ بررسی نمی‌کنند کد و پایگاه‌دادهٔ شما با متن فارسی چه می‌کنند
    Unicode CLDR / ICUThe reference for Persian collation, digits and calendarsمرجع مرتب‌سازی، ارقام و تقویم فارسیThe specification, not a test of what each runtime on your machine does; persianprobe runs the real thingخود استاندارد است، نه آزمون کاری که هر runtime روی دستگاه شما می‌کند؛ persianprobe چیز واقعی را اجرا می‌کند

    FAQپرسش‌های متداول

    Questions people ask.پرسش‌هایی که می‌پرسند.

    Which runtimes does it need?به کدام runtimeها نیاز دارد؟

    Only Python 3.9+. Node, Bun, Perl, SQLite (through Python's sqlite3), jq, Go and awk are used when they are found on PATH; the rest are skipped.فقط پایتون ۳٫۹ به بالا. Node، Bun، Perl، SQLite (از طریق sqlite3 پایتون)، jq، Go و awk در صورت یافتن در PATH استفاده می‌شوند؛ بقیه رد می‌شوند.

    Is "false" for علی = علي a bug?آیا «false» برای علی = علي باگ است؟

    Not in Unicode: they are different characters. It is listed because it splits user data in two ("علی" and "علي" in one unique index). xray finds those characters and --fix normalizes them.در یونیکد نه: نویسه‌هایشان فرق دارد. فهرست شده چون داده‌ٔ کاربر را دو تکه می‌کند («علی» و «علي» در یک ایندکس یکتا). xray این نویسه‌ها را پیدا می‌کند و ‎--fix‎ نرمالشان می‌کند.

    Does it send anything anywhere?آیا چیزی را جایی می‌فرستد؟

    No. It runs local interpreters only, uses no network and writes only to a temp directory.نه. فقط مفسرهای محلی را اجرا می‌کند، شبکه ندارد و فقط در پوشهٔ موقت می‌نویسد.

    How does it help an AI agent?چطور به ایجنت هوش مصنوعی کمک می‌کند؟

    Paste docs/AGENTS.snippet.md into AGENTS.md or CLAUDE.md so the assistant checks Persian behaviour before it writes an English-shaped validator, sort or parser. --json and --strict (exit 1 on any trap) work in CI.فایل docs/AGENTS.snippet.md را در AGENTS.md یا CLAUDE.md بگذارید تا دستیار پیش از نوشتن اعتبارسنج، sort یا parser انگلیسی‌شکل رفتار فارسی را بررسی کند. ‎--json‎ و ‎--strict‎ (کد ۱ با هر تله) در CI کار می‌کنند.