这个 String.Replace 方法在做什么?
What is this String.Replace method doing?
我正在尝试将此 Javascript 代码移植到另一种语言 (Xojo):
Vertices.fromPath = function(path, body) {
var pathPattern = /L?\s*([\-\d\.e]+)[\s,]*([\-\d\.e]+)*/ig,
points = [];
path.replace(pathPattern, function(match, x, y) {
points.push({ x: parseFloat(x), y: parseFloat(y) });
});
return Vertices.create(points, body);
};
我知道路径应该是一个包含 x y 对数字的字符串(采用 SVG 格式,如 "L 50 25 L 100 10"
)。我是否正确地认为这会将较早的字符串拆分为两个对象 50,25
和 100,10
然后将它们推入点数组?
不确定您是否知道 /L?\s*([\-\d\.e]+)[\s,]*([\-\d\.e]+)*/ig
是正则表达式搜索字符串。
如果我这么快破译,我会说它在开始时寻找一个可选的 "L",然后是可选的空格,然后是一个数字(即任何包含数字、句点、减号或 "e")、空格或逗号、另一个数字和数字两边的括号表示这些是在 replace()
调用中传递给函数的匹配值。最后的 "ig" 是选项,其中 "i" 表示忽略大小写 IIRC。
因此,该代码似乎只获取两个数字,可选地在前面加上 "L"。然后它将这些数字读入 x 和 y,并将它们附加到 points
数组。
在 Xojo 中,您必须在循环中执行此操作(Xojo 不支持本地函数),使用 RegEx class 重复解析字符串。要将扫描的数字转换为双精度数,请使用 Val()
函数。
虽然您问题中的正则表达式确实会匹配单个 'L' 字母后的两个数字,但它还会匹配许多其他无法解析为有效数字的内容。
你是对的,这段代码将创建两个对象,它们的 X 和 Y 属性由匹配的数字填充。
使用 Realbasic.Points 保存坐标,可以通过以下 Xojo 代码段实现此功能:
Dim inString As String = "L 50 25 L 100 10"
Dim outArray(-1) As Realbasic.Point
Dim rx As New RegEx()
Dim match As RegExMatch
rx.SearchPattern = "L?\s*([\-\d.e]+)[\s,]*([\-\d.e]+)*"
match = rx.Search(inString) // Get the first matching part of the string, or nil if there's no match
While match <> nil
dim x As Integer = match.SubExpressionString(1).Val() // X coordinate is captured by the first group
dim y As Integer = match.SubExpressionString(2).Val() // Y coordinate is captured by the second group
dim p As new REALbasic.Point(x, y)
outArray.Append(p)
match = rx.Search() // Get the next matching part, or nil if there's no more
Wend
如果您只需要匹配数字并希望在 String->Double 转换期间防止错误,您应该将正则表达式模式更新为如下内容:
"L?\s+(\-?\d+(?:\.\d+)?(?:e-?\d+)?)[\s,]+(\-?\d+(?:\.\d+)?(?:e-?\d+)?)"
原始模式会匹配 'Lee ...---...',这个更新后的模式需要在 'L' 和数字之间至少有一个 space,并且不会匹配可能是部分的字符的数字,但它们不构成有效的数字表示形式。
我正在尝试将此 Javascript 代码移植到另一种语言 (Xojo):
Vertices.fromPath = function(path, body) {
var pathPattern = /L?\s*([\-\d\.e]+)[\s,]*([\-\d\.e]+)*/ig,
points = [];
path.replace(pathPattern, function(match, x, y) {
points.push({ x: parseFloat(x), y: parseFloat(y) });
});
return Vertices.create(points, body);
};
我知道路径应该是一个包含 x y 对数字的字符串(采用 SVG 格式,如 "L 50 25 L 100 10"
)。我是否正确地认为这会将较早的字符串拆分为两个对象 50,25
和 100,10
然后将它们推入点数组?
不确定您是否知道 /L?\s*([\-\d\.e]+)[\s,]*([\-\d\.e]+)*/ig
是正则表达式搜索字符串。
如果我这么快破译,我会说它在开始时寻找一个可选的 "L",然后是可选的空格,然后是一个数字(即任何包含数字、句点、减号或 "e")、空格或逗号、另一个数字和数字两边的括号表示这些是在 replace()
调用中传递给函数的匹配值。最后的 "ig" 是选项,其中 "i" 表示忽略大小写 IIRC。
因此,该代码似乎只获取两个数字,可选地在前面加上 "L"。然后它将这些数字读入 x 和 y,并将它们附加到 points
数组。
在 Xojo 中,您必须在循环中执行此操作(Xojo 不支持本地函数),使用 RegEx class 重复解析字符串。要将扫描的数字转换为双精度数,请使用 Val()
函数。
虽然您问题中的正则表达式确实会匹配单个 'L' 字母后的两个数字,但它还会匹配许多其他无法解析为有效数字的内容。 你是对的,这段代码将创建两个对象,它们的 X 和 Y 属性由匹配的数字填充。
使用 Realbasic.Points 保存坐标,可以通过以下 Xojo 代码段实现此功能:
Dim inString As String = "L 50 25 L 100 10"
Dim outArray(-1) As Realbasic.Point
Dim rx As New RegEx()
Dim match As RegExMatch
rx.SearchPattern = "L?\s*([\-\d.e]+)[\s,]*([\-\d.e]+)*"
match = rx.Search(inString) // Get the first matching part of the string, or nil if there's no match
While match <> nil
dim x As Integer = match.SubExpressionString(1).Val() // X coordinate is captured by the first group
dim y As Integer = match.SubExpressionString(2).Val() // Y coordinate is captured by the second group
dim p As new REALbasic.Point(x, y)
outArray.Append(p)
match = rx.Search() // Get the next matching part, or nil if there's no more
Wend
如果您只需要匹配数字并希望在 String->Double 转换期间防止错误,您应该将正则表达式模式更新为如下内容:
"L?\s+(\-?\d+(?:\.\d+)?(?:e-?\d+)?)[\s,]+(\-?\d+(?:\.\d+)?(?:e-?\d+)?)"
原始模式会匹配 'Lee ...---...',这个更新后的模式需要在 'L' 和数字之间至少有一个 space,并且不会匹配可能是部分的字符的数字,但它们不构成有效的数字表示形式。