devoashim/regxdomdocument
Composer 安装命令:
composer require devoashim/regxdomdocument
包简介
Pure regex-based DOM manipulation library with React/JSX template literal support. No DOMDocument, no XML parsing - just regex magic!
README 文档
README
Pure regex-based DOM manipulation library with React/JSX Template Literal Support. No DOMDocument, no XML parsing - just regex magic!
Perfect for preserving exact HTML structure, React/Vue components, and template variables.
Installation
composer require devoashim/regxdomdocument
Table of Contents
- Quick Start
- Loading HTML
- Finding Elements
- Getting Content
- Setting Content
- Attributes & Classes
- Template Literals (React/JSX)
- Removing Elements
- Iteration & Filtering
- Saving & Output
- Advanced Usage - RegexHelper
- Method Reference
- Use Cases
Quick Start
Basic HTML Manipulation
use devoashim\regxdomdocument\XDOM; $dom = XDOM::load($html); // Find and modify elements $dom->find('#app')->setInnerHTML('<Component />'); $dom->find('.header')->addClass('active'); echo $dom->html();
Template Literal Generation
Convert static className to dynamic React template literal:
$dom = XDOM::loadFromFile('index.html'); // Convert static to dynamic $dom->find('.stricky-header') ->setDynamicClass('isStick', 'stricky-fixed'); // Output HTML echo $dom->html();
Before:
<div className="stricky-header stricked-menu main-menu">
After:
<div className={`stricky-header stricked-menu main-menu ${isStick ? 'stricky-fixed' : ''}`}>
Loading HTML
Returns: XDOM instance
// From string $dom = XDOM::load($htmlString); // From file $dom = XDOM::loadFromFile('/path/to/file.html'); // From Laravel Storage $path = Storage::disk('public')->path('index.html'); $dom = XDOM::loadFromFile($path);
Finding Elements
Returns: RegexNodeCollection
// By ID $element = $dom->find('#header'); $element = $dom->find('#main-content'); // By Class $elements = $dom->find('.container'); $elements = $dom->find('.nav-item'); // By Tag $elements = $dom->find('div'); $elements = $dom->find('nav'); $elements = $dom->find('section'); // Combined Selectors $element = $dom->find('div#main'); // Tag + ID $element = $dom->find('section#about'); $elements = $dom->find('div.container'); // Tag + Class $elements = $dom->find('nav.main-nav'); // Descendant (parent child) $elements = $dom->find('header nav'); $elements = $dom->find('div .content'); $elements = $dom->find('main section');
Getting Content
String Returns
// Get inner HTML (content between tags) $content = $dom->find('#app')->innerHTML(); // <div id="app">THIS CONTENT</div> // Returns: "THIS CONTENT" // Get outer HTML (full element with tags) $html = $dom->find('#app')->outerHTML(); // Returns: "<div id="app">Content</div>" // Get text content (strip all HTML) $text = $dom->find('#app')->text(); // <div id="app"><p>Hello <b>World</b></p></div> // Returns: "Hello World" // Get complete HTML document $fullHtml = $dom->html(); // Get attribute value $value = $dom->find('#app')->attr('data-value'); $id = $dom->find('div')->attr('id'); $class = $dom->find('nav')->attr('class');
Array Returns
// Get first element $first = $dom->find('.item')->first(); // Returns: ['html' => '...', 'position' => ..., 'tag' => '...'] // Get last element $last = $dom->find('.item')->last(); // Get element by index $third = $dom->find('.item')->get(2); // 0-based index // Get all matches as array $matches = $dom->find('.item')->getMatches(); // Returns: [ // ['html' => '<div class="item">1</div>', 'position' => 0, 'tag' => 'div', 'type' => 'full'], // ['html' => '<div class="item">2</div>', 'position' => 50, 'tag' => 'div', 'type' => 'full'], // ]
Boolean & Integer Returns
// Count elements $count = $dom->find('.item')->count(); echo "Found $count items"; // Check if has attribute if ($dom->find('#app')->hasAttr('data-loaded')) { echo "Has data-loaded attribute"; } // Check if has class if ($dom->find('#app')->hasClass('active')) { echo "Has active class"; } // Check if empty if ($dom->find('.item')->isEmpty()) { echo "No items found"; } // Check if not empty if ($dom->find('.item')->isNotEmpty()) { echo "Items found!"; }
Setting Content
Returns: RegexNodeCollection (chainable)
// Set inner HTML (PRESERVES EXACT CONTENT - no encoding) $dom->find('#app')->setInnerHTML('<Menu /> <Dashboard />'); // Perfect for React/Vue components! // Set outer HTML (replace entire element) $dom->find('#old')->setOuterHTML('<section id="new">Content</section>'); // Before: <div id="old">...</div> // After: <section id="new">Content</section> // Set text (HTML encoded for safety) $dom->find('#title')->setText('Hello & Welcome'); // Output: Hello & Welcome // Append content (add at end, inside element) $dom->find('#list')->append('<li>New Item</li>'); // Prepend content (add at start, inside element) $dom->find('#list')->prepend('<li>First Item</li>'); // Insert before element $dom->find('#main')->before('<header>Header</header>'); // Insert after element $dom->find('#main')->after('<footer>Footer</footer>');
Attributes & Classes
Returns: RegexNodeCollection (chainable)
// Set single attribute $dom->find('#app') ->attr('data-component', 'main') ->attr('data-version', '2.0') ->attr('data-loaded', 'true'); // Remove attribute $dom->find('#app')->removeAttr('data-old'); // Add single class $dom->find('#app') ->addClass('active') ->addClass('loaded') ->addClass('ready'); // Add multiple classes $dom->find('.header')->addClasses('active loaded ready'); $dom->find('.header')->addClasses(['active', 'loaded', 'ready']); // Remove class $dom->find('#app') ->removeClass('old') ->removeClass('hidden'); // Toggle class $dom->find('#app')->toggleClass('active'); // If has 'active' → removes it // If no 'active' → adds it // Set all classes (replace existing) $dom->find('.header')->setClasses('new-class another-class'); // Conditional class (PHP-side) $dom->find('.header')->conditionalClass('active', $isActive);
Template Literals (React/JSX)
Single Conditional Class
$dom->find('.header')->setDynamicClass('isStick', 'sticky-fixed');
Result:
<div className={`header ${isStick ? 'sticky-fixed' : ''}`}>
Multiple Conditional Classes
$dom->find('.header') ->setMultipleConditionalClasses([ 'isStick' => 'sticky-fixed', 'isTransparent' => 'transparent', 'isScrolled' => 'scrolled' ]);
Result:
<div className={`header ${isStick ? 'sticky-fixed' : ''} ${isTransparent ? 'transparent' : ''} ${isScrolled ? 'scrolled' : ''}`}>
Custom Template Expression
$dom->find('.button') ->setTemplateExpression('className', 'btn ${type === "primary" ? "btn-primary" : "btn-secondary"}');
Result:
<button className={`btn ${type === "primary" ? "btn-primary" : "btn-secondary"}`}>
Convert class to className
$dom->find('div')->convertToClassName();
Before: <div class="header">
After: <div className="header">
Removing Elements
Returns: RegexNodeCollection (chainable)
// Remove elements from DOM $dom->find('.old-widget')->remove(); $dom->find('#deprecated')->remove();
Iteration & Filtering
Returns: RegexNodeCollection (chainable) or transformed data
// Iterate each element $dom->find('.item')->each(function($element, $index) { echo "Item $index: " . $element['html'] . "\n"; }); // Map elements (transform) $texts = $dom->find('.item')->map(function($element, $index) { return strip_tags($element['html']); }); // Returns: Collection or array // Filter elements $filtered = $dom->find('.item')->filter(function($element, $index) { return strpos($element['html'], 'active') !== false; }); // Returns: RegexNodeCollection with filtered elements
Saving & Output
Various Return Types
// Get HTML as string $html = $dom->html(); // Set HTML $dom->setHtml($newHtmlString); // Returns: XDOM (chainable) // Save to file $dom->saveToFile('/path/to/output.html'); // Returns: XDOM (chainable) // Save to Laravel Storage $dom->saveToStorage('public/output.html'); // Returns: XDOM (chainable) // Return as Laravel Response return $dom->toResponse(); // Returns: Response // Automatically sets Content-Type: text/html
Advanced Usage - RegexHelper
For direct regex operations without the fluent interface:
use devoashim\regxdomdocument\RegexHelper;
Extract Content
Returns: string or null
// Extract full element (with tags) $content = RegexHelper::extractTagContent($html, 'div', 'header', 'class'); // From: <div class="header">Content</div> // Returns: "<div class="header">Content</div>" $content = RegexHelper::extractTagContent($html, 'section', 'main', 'id'); // From: <section id="main">Content</section> // Returns: "<section id="main">Content</section>" // Extract inner content (without tags) $inner = RegexHelper::extractInnerContent($html, 'div', 'container', 'class'); // From: <div class="container"><p>Text</p></div> // Returns: "<p>Text</p>"
Replace Content
Returns: string
// Replace full element $newHtml = RegexHelper::replaceTagContent( $html, 'div', 'header', '<div class="header"><Header /></div>' ); // Replace inner content only $newHtml = RegexHelper::replaceInnerContent( $html, 'div', 'content', '<Component />' );
Find Multiple Elements
Returns: array
// Find all matching elements $widgets = RegexHelper::findAllTags($html, 'div', 'widget', 'class'); // Returns: ['<div class="widget">1</div>', '<div class="widget">2</div>', ...] foreach ($widgets as $i => $widget) { echo "Widget $i: $widget\n"; }
Remove Elements
Returns: string
// Remove all matching elements $cleanHtml = RegexHelper::removeAllTags($html, 'div', 'ads', 'class');
Check Existence
Returns: bool
// Check if element exists if (RegexHelper::hasTag($html, 'div', 'header', 'class')) { echo "Header exists!"; }
Attribute Helpers
Returns: array or string
// Extract all attributes from tag $tag = '<div class="box" id="main" data-value="123">'; $attrs = RegexHelper::extractAttributes($tag); // Returns: ['class' => 'box', 'id' => 'main', 'data-value' => '123'] // Replace attribute value $newTag = RegexHelper::replaceAttribute($tag, 'class', 'new-box active'); // Returns: '<div class="new-box active" id="main" data-value="123">'
Template Literal Generation
Returns: string
// Convert to template literal $reactHtml = RegexHelper::setDynamicClassName( $html, 'div', 'header', 'isStick', 'sticky-fixed' );
Method Reference
XDOM Methods
| Method | Returns | Description |
|---|---|---|
load($html) |
XDOM | Load HTML string |
loadFromFile($path) |
XDOM | Load from file |
find($selector) |
RegexNodeCollection | Find elements |
html() |
string | Get full HTML |
setHtml($html) |
XDOM | Set HTML (chainable) |
saveToFile($path) |
XDOM | Save to file (chainable) |
saveToStorage($path) |
XDOM | Save to Laravel Storage |
toResponse() |
Response | Return as Laravel response |
RegexNodeCollection Methods
| Method | Returns | Chainable | Description |
|---|---|---|---|
innerHTML() |
string | No | Get inner HTML |
outerHTML() |
string | No | Get outer HTML |
text() |
string | No | Get text content |
attr($name) |
string/null | No | Get attribute value |
attr($name, $value) |
RegexNodeCollection | Yes | Set attribute |
hasAttr($name) |
bool | No | Check if has attribute |
removeAttr($name) |
RegexNodeCollection | Yes | Remove attribute |
addClass($class) |
RegexNodeCollection | Yes | Add single class |
addClasses($classes) |
RegexNodeCollection | Yes | Add multiple classes |
removeClass($class) |
RegexNodeCollection | Yes | Remove class |
toggleClass($class) |
RegexNodeCollection | Yes | Toggle class |
setClasses($classes) |
RegexNodeCollection | Yes | Set all classes |
hasClass($class) |
bool | No | Check if has class |
conditionalClass($class, $condition) |
RegexNodeCollection | Yes | Add class if condition true |
setInnerHTML($html) |
RegexNodeCollection | Yes | Set inner HTML |
setOuterHTML($html) |
RegexNodeCollection | Yes | Replace entire element |
setText($text) |
RegexNodeCollection | Yes | Set text (encoded) |
append($html) |
RegexNodeCollection | Yes | Append inside element |
prepend($html) |
RegexNodeCollection | Yes | Prepend inside element |
before($html) |
RegexNodeCollection | Yes | Insert before element |
after($html) |
RegexNodeCollection | Yes | Insert after element |
remove() |
RegexNodeCollection | Yes | Remove element |
setDynamicClass($var, $class) |
RegexNodeCollection | Yes | Add template literal |
setMultipleConditionalClasses($array) |
RegexNodeCollection | Yes | Multiple conditionals |
setTemplateExpression($attr, $expr) |
RegexNodeCollection | Yes | Custom template |
convertToClassName() |
RegexNodeCollection | Yes | class → className |
each($callback) |
RegexNodeCollection | Yes | Iterate elements |
map($callback) |
Collection/array | No | Transform elements |
filter($callback) |
RegexNodeCollection | No | Filter elements |
first() |
array/null | No | Get first element |
last() |
array/null | No | Get last element |
get($index) |
array/null | No | Get by index |
getMatches() |
array | No | Get all matches |
count() |
int | No | Count elements |
isEmpty() |
bool | No | Check if empty |
isNotEmpty() |
bool | No | Check if not empty |
RegexHelper Static Methods
| Method | Returns | Description |
|---|---|---|
extractTagContent($html, $tag, $id, $type) |
string/null | Extract full element |
extractInnerContent($html, $tag, $id, $type) |
string/null | Extract inner content |
replaceTagContent($html, $tag, $id, $new, $type) |
string | Replace full element |
replaceInnerContent($html, $tag, $id, $new, $type) |
string | Replace inner content |
findAllTags($html, $tag, $id, $type) |
array | Find all matching |
removeAllTags($html, $tag, $id, $type) |
string | Remove all matching |
hasTag($html, $tag, $id, $type) |
bool | Check if exists |
extractAttributes($tag) |
array | Get all attributes |
replaceAttribute($tag, $name, $value) |
string | Replace attribute value |
setDynamicClassName($html, $tag, $id, $var, $class) |
string | Create template literal |
Note: $type parameter can be 'class' (default) or 'id'
Use Cases
1. React Component Conversion
$dom = XDOM::loadFromFile('template.html'); $dom->find('.header')->setInnerHTML('<Header />'); $dom->find('.navigation')->setInnerHTML('<Navigation />'); $dom->find('.content')->setInnerHTML('<Content />'); $dom->find('.footer')->setInnerHTML('<Footer />'); echo $dom->html();
2. Sticky Header with Template Literal
$dom = XDOM::loadFromFile('index.html'); $dom->find('.stricky-header') ->setDynamicClass('isStick', 'stricky-fixed') ->attr('data-component', 'header'); echo $dom->html();
3. Dynamic Navigation
$dom->find('.nav-item') ->setDynamicClass('isActive', 'active');
Result:
<li className={`nav-item ${isActive ? 'active' : ''}`}>
Add ref attribute to element's opening tag
$dom->find('.main-header')->addRef('headerRef');
Before:
<header className="main-header">
After:
<header ref={headerRef} className="main-header">
4. Template Variable Injection
$dom = XDOM::load($template); $dom->find('#username')->setInnerHTML('{{user.name}}'); $dom->find('#email')->setInnerHTML('{{user.email}}'); $dom->find('#role')->setInnerHTML('{{user.role}}'); return $dom->html();
5. Batch Widget Processing
$dom->find('.widget') ->addClass('active') ->addClass('featured') ->attr('data-loaded', 'true');
6. Complex Component Building
$dom->find('#app') ->setInnerHTML('<App />') ->addClass('loaded') ->addClass('active') ->attr('data-component', 'root') ->attr('data-version', '2.0') ->prepend('<!-- App Start -->') ->append('<!-- App End -->');
7. Conditional Modifications
$element = $dom->find('#app'); if ($element->hasClass('old')) { $element->removeClass('old')->addClass('new'); } if (!$element->hasAttr('data-version')) { $element->attr('data-version', '2.0'); }
8. Extract and Replace Sections
// Extract $header = RegexHelper::extractTagContent($html, 'div', 'header', 'class'); // Replace $newHtml = RegexHelper::replaceTagContent( $html, 'div', 'header', '<header><HeaderComponent /></header>' );
9. Navigation Menu Processing
// Find nav inside header only $nav = $dom->find('header nav'); if ($nav->isNotEmpty()) { $nav->setInnerHTML('<Navigation items={menuItems} />'); }
10. Multi-Step Content Wrapping
$dom->find('#content') ->before('<div class="wrapper">') ->after('</div>') ->addClass('inner-content');
Method Chaining Examples
All modification methods return RegexNodeCollection, enabling powerful chaining:
// Example 1: Complete component setup $dom->find('#app') ->setInnerHTML('<App />') ->addClass('loaded') ->addClass('active') ->attr('data-component', 'root') ->attr('data-version', '2.0') ->prepend('<!-- App Start -->') ->append('<!-- App End -->'); // Example 2: Style and configure widget $dom->find('.widget') ->addClass('active') ->addClass('featured') ->attr('data-priority', 'high') ->setInnerHTML('<WidgetComponent />'); // Example 3: Update card styling $dom->find('.card') ->removeClass('old-style') ->addClass('new-style') ->attr('data-updated', 'true') ->setInnerHTML('<CardComponent />');
Key Features
Exact Content Preservation - No HTML encoding or modification
React/Vue/JSX Support - Perfect for component templates
Template Literals - Generate dynamic className with conditionals
Template Variables - Works with {{mustache}}, {blade}, etc.
Pure Regex - Fast, lightweight, no dependencies
Method Chaining - Clean, readable code
Laravel Integration - Storage and Response helpers
No DOM Parser - Preserves exact formatting and structure
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License.
Credits
Created by devoashim
Support
- GitHub Issues: Create an issue
- Documentation: Full API reference and examples included
⭐ Star Us!
If you find this package useful, please consider giving it a star on GitHub!
Remember:
- All content is preserved EXACTLY (no encoding)
- Perfect for React/Vue/Angular components
- Works seamlessly with template variables
- Pure regex - fast and lightweight
- Method chaining for clean, maintainable code
Last Updated: 2024 Version: Complete Merged Guide
devoashim/regxdomdocument 适用场景与选型建议
devoashim/regxdomdocument 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 3 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 01 月 26 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「parser」 「html」 「dom」 「laravel」 「regex」 「react」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 devoashim/regxdomdocument 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 devoashim/regxdomdocument 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 devoashim/regxdomdocument 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Texy converts plain text in easy to read Texy syntax into structurally valid (X)HTML. It supports adding of images, links, nested lists, tables and has full support for CSS. Texy supports hyphenation of long words (which reflects language rules), clickable emails and URL (emails are obfuscated again
A library that provides basic utilities for creating HTML documents.
A bridge between SimpleXML and the DOM extension, plus a bunch of convenience methods
Easy to use SDK with grabber for multiple platforms at once like YouTube, Dailymotion, Facebook and more.
BigPipe: Pipelining web pages for high performance built in PHP.
Load DOM document safety
统计信息
- 总下载量: 3
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 27
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-01-26