Skip to content

Commit

Permalink
docs(ReadRTF): update readme (#65)
Browse files Browse the repository at this point in the history
  • Loading branch information
Snoopy1866 authored Jan 17, 2025
1 parent 3dac3b5 commit 7e22b73
Showing 1 changed file with 38 additions and 38 deletions.
76 changes: 38 additions & 38 deletions docs/ReadRTF.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,12 @@ OUTDATA = t_7_1_1

默认情况下,宏程序将在输出的 SAS 数据集中自动删除下表中的控制字:

| 控制字 | 含义 | 正则表达式 |
| ----------- | ---------- | ---------------------------------- |
| {} | 空的 Group | {\s\\\*}\|(?<!\\\\)[{}] |
| \li*N* | 缩进 | \\\\li\\d+ |
| \super | 上标 | {\\\\super.\\\*?}\|\\\\super[^\\]+ |
| \nosupersub | 取消上下标 | \\\\nosupersub |
| 控制字 | 含义 | 正则表达式 |
| ----------- | ---------- | ---------------------------------------------- |
| {} | 空的 Group | `{\s*}\|(?<!\\)[{}]` |
| \li*N* | 缩进 | `\\li\d+` |
| \super | 上标 | `\{?\\super\s*((?:\\[\\\{\}]\|[^\\\{\}])+)\}?` |
| \nosupersub | 取消上下标 | `\\nosupersub` |

---

Expand Down Expand Up @@ -170,21 +170,21 @@ RTF 文件单行字符串没有限制长度,为确保读取的 RTF 标记字

1. 使用以下正则表达式识别出现内嵌换行符的表头

```
/^(\\pard\\plain\\intbl\\keepn\\sb\d*\\sa\d*\\q[lcr]\\f\d*\\fs\d*\\cf\d*\{.*){\\line}$/o
```
```
/^(\\pard\\plain\\intbl\\keepn\\sb\d*\\sa\d*\\q[lcr]\\f\d*\\fs\d*\\cf\d*\{.*){\\line}$/o
```

2. 在上一步成功匹配正则表达式的基础上,连续使用以下正则表达式识别连续的内嵌换行符

```
/^(.*){\\line}$/o
```
```
/^(.*){\\line}$/o
```

3. 直到使用以下正则表达式识别到单元格的结束位置

```
^(.*\\cell})$/o
```
```
^(.*\\cell})$/o
```

上述步骤中,步骤 2 可能会重复多次,每次识别到内嵌的换行符时,都将文本提取出来,并与上一步骤提取的文本拼接,同时删除当前行,直到步骤 3,此时所有内嵌的换行符均已删除,拼接后的文本即为单元格内的完整文本。

Expand All @@ -196,47 +196,47 @@ RTF 文件单行字符串没有限制长度,为确保读取的 RTF 标记字

1. 使用以下正则表达式匹配定义了大纲级别的表格标题

```
/\\outlinelevel\d/o
```
```
/\\outlinelevel\d/o
```

2. 使用以下正则表达式匹配表格表头的开始定义位置

```
/\\trowd\\trkeep\\trhdr\\trq[lcr]/o
```
```
/\\trowd\\trkeep\\trhdr\\trq[lcr]/o
```

上述正则表达式中,关键的控制字是 `\trhdr`,它表示表格的表头行,出现在当前表格的所有页面之前
上述正则表达式中,关键的控制字是 `\trhdr`,它表示表格的表头行,出现在当前表格的所有页面之前

3. 使用以下正则表达式匹配表格表头单元格的右边框位置

```
/\\clbrdr[tlbr]\\brdrs\\brdrw\d*\\brdrcf\d*(?:\\clbrdr[tlbr]\\brdrs\\brdrw\d*\\brdrcf\d*)*\\cltxlrt[bl]\\clvertal[tcb](?:\\clcbpat\d*)?\\cellx(\d+)/o
```
```
/\\clbrdr[tlbr]\\brdrs\\brdrw\d*\\brdrcf\d*(?:\\clbrdr[tlbr]\\brdrs\\brdrw\d*\\brdrcf\d*)*\\cltxlrt[bl]\\clvertal[tcb](?:\\clcbpat\d*)?\\cellx(\d+)/o
```

上述正则表达式中,关键的控制字是 `\cellx` 其中 `\d+` 代表单元格右边框的位置。某些表格的表头含有多行,且包含单元格的合并,根据不同行的单元格的右边框位置,可以计算上一行某个单元格是由哪几个单元格合并而来,这些信息在后续给输出数据集定义标签时会有用,利用这些信息可以精确控制多行的标签是如何组合的,防止标签被定义在错误的变量上。
上述正则表达式中,关键的控制字是 `\cellx` 其中 `\d+` 代表单元格右边框的位置。某些表格的表头含有多行,且包含单元格的合并,根据不同行的单元格的右边框位置,可以计算上一行某个单元格是由哪几个单元格合并而来,这些信息在后续给输出数据集定义标签时会有用,利用这些信息可以精确控制多行的标签是如何组合的,防止标签被定义在错误的变量上。

4. 使用以下正则表达式匹配数据行

```
^\\pard\\plain\\intbl(?:\\keepn)?\\sb\d*\\sa\d*\\q[lcr]\\f\d*\\fs\d*\\cf\d*\{((?:\\'[0-9A-F]{2}|\\u\d{1,5};|[\x20-\x7e])*)\\cell\}$/o
```
```
^\\pard\\plain\\intbl(?:\\keepn)?\\sb\d*\\sa\d*\\q[lcr]\\f\d*\\fs\d*\\cf\d*\{((?:\\'[0-9A-F]{2}|\\u\d{1,5};|[\x20-\x7e])*)\\cell\}$/o
```

上述正则表达式中,包含了 3 种类型的数据编码形式:
上述正则表达式中,包含了 3 种类型的数据编码形式:

- `\\'[0-9A-F]{2}` : GBK
- `\\u\d{1,5};` : UTF-8
- `[\x20-\x7e]` : ASCII
- `\\'[0-9A-F]{2}` : GBK
- `\\u\d{1,5};` : UTF-8
- `[\x20-\x7e]` : ASCII

其中 GBK 和 UTF-8 字符是以转义字符表示的,需要进一步转换成以 SAS 当前环境下的编码存储的字符串。
其中 GBK 和 UTF-8 字符是以转义字符表示的,需要进一步转换成以 SAS 当前环境下的编码存储的字符串。

5. 使用以下正则表达式匹配分节符

```
/\\sect\\sectd\\linex\d*\\endnhere\\pgwsxn\d*\\pghsxn\d*\\lndscpsxn\\headery\d*\\footery\d*\\marglsxn\d*\\margrsxn\d*\\margtsxn\d*\\margbsxn\d*/o
```
```
/\\sect\\sectd\\linex\d*\\endnhere\\pgwsxn\d*\\pghsxn\d*\\lndscpsxn\\headery\d*\\footery\d*\\marglsxn\d*\\margrsxn\d*\\margtsxn\d*\\margbsxn\d*/o
```

某些 RTF 为了在每一页中重复表格标题,可能会使用分节符,这样会导致读取 RTF 文件时,从第 2 页开始,页脚的文本也被当做数据行被输出到数据集中,为了解决这一问题,使用这个正则表达式识别到分节符后,应当再次寻找定义了大纲级别的表格标题,在分节符之后,定义了大纲级别的表格标题之前的任何 RTF 标记文本都将被忽略。
某些 RTF 为了在每一页中重复表格标题,可能会使用分节符,这样会导致读取 RTF 文件时,从第 2 页开始,页脚的文本也被当做数据行被输出到数据集中,为了解决这一问题,使用这个正则表达式识别到分节符后,应当再次寻找定义了大纲级别的表格标题,在分节符之后,定义了大纲级别的表格标题之前的任何 RTF 标记文本都将被忽略。

### 5. 如何将转义字符转换为正常可读的字符串

Expand Down

0 comments on commit 7e22b73

Please sign in to comment.